Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.86% covered (success)
92.86%
13 / 14
83.33% covered (warning)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiVersion
92.86% covered (success)
92.86%
13 / 14
83.33% covered (warning)
83.33%
5 / 6
9.03
0.00% covered (danger)
0.00%
0 / 1
 latest
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 allDescending
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 tryFromString
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 isAtLeast
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 edition
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 ontologyVersionIri
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace LambdaTwelve\OneRecord\Spec;
6
7use LogicException;
8
9/**
10 * A ONE Record API specification version this package can speak.
11 *
12 * The version travels in the media type parameter of Accept and Content-Type
13 * (`application/ld+json; version=2.3.0`). The server negotiates it per request
14 * and the client picks it per partner from their server information, so a 2.2
15 * partner and a 2.3 partner are both served without configuration.
16 */
17enum ApiVersion: string
18{
19    case V2_2_0 = '2.2.0';
20    case V2_3_0 = '2.3.0';
21
22    public static function latest(): self
23    {
24        $cases = self::cases();
25
26        return $cases[\count($cases) - 1];
27    }
28
29    /**
30     * Highest first, the order server information advertises and negotiation prefers.
31     *
32     * @return non-empty-list<self>
33     */
34    public static function allDescending(): array
35    {
36        $cases = array_reverse(self::cases());
37        \assert($cases !== []);
38
39        return $cases;
40    }
41
42    /**
43     * Lenient parsing for the media type parameter: "2.3", "2.3.0" and "v2.3.0"
44     * all mean the same thing to a partner, and a version we do not know is null.
45     */
46    public static function tryFromString(string $version): ?self
47    {
48        $normalised = ltrim(trim($version), 'vV');
49        if (preg_match('/^\d+\.\d+$/', $normalised) === 1) {
50            $normalised .= '.0';
51        }
52
53        return self::tryFrom($normalised);
54    }
55
56    public function isAtLeast(self $other): bool
57    {
58        return version_compare($this->value, $other->value, '>=');
59    }
60
61    public function edition(): Edition
62    {
63        foreach (Edition::cases() as $edition) {
64            if ($edition->apiVersion() === $this) {
65                return $edition;
66            }
67        }
68
69        throw new LogicException("No edition declares API version {$this->value}.");
70    }
71
72    /**
73     * The owl:versionIRI of the API ontology at this version.
74     */
75    public function ontologyVersionIri(): string
76    {
77        return Namespaces::API_ONTOLOGY . '/' . $this->value;
78    }
79}