+
+ private function composeType(string $type) : string {
+ $part = "[^()<>@,;:\\\"\/\[\]?.=[:space:][:cntrl:]]+";
+ if (preg_match("/^$part\/$part\$/", $type)) {
+ return $type;
+ }
+
+ switch (substr($type, 0, 1)) {
+ case "+":
+ case ".":
+ case "":
+ break;
+ default:
+ $type = ".$type";
+ break;
+ }
+ return "application/vnd.github.v{$this->version}$type";
+ }
+
+ private function extractType(string $type) : string {
+ return preg_replace("/
+ (?:application\/(?:vnd\.github(?:\.v{$this->version})?)?)
+ (?|
+ \. ([^.+]+)
+ | (?:\.[^.+]+)?\+? (json)
+ )/x", "\\1", $type);
+ }
+
+ private function extractTypeFromParams(Params $params) : string {
+ return $this->extractType(current(array_keys($params->params)));
+ }
+
+ private function extractTypeFromHeader(Header $header) : string {
+ if (strcasecmp($header->name, "Content-Type")) {
+ throw new InvalidArgumentException(
+ "Expected Content-Type header, got ". $header->name);
+ }
+ return $this->extractTypeFromParams($header->getParams());
+ }