Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.89% covered (warning)
88.89%
8 / 9
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
OperationObject
88.89% covered (warning)
88.89%
8 / 9
80.00% covered (warning)
80.00%
4 / 5
8.09
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 literal
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 isLiteral
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isBlankNode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 toLiteral
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
1<?php
2
3declare(strict_types=1);
4
5namespace LambdaTwelve\OneRecord\Change;
6
7use LambdaTwelve\OneRecord\Rdf\Literal;
8use LambdaTwelve\OneRecord\Spec\Namespaces;
9use LogicException;
10
11/**
12 * api:OperationObject: the object of a triple as a (datatype, value) pair.
13 * An XSD datatype means a literal; any other datatype is the class of the
14 * node the value identifies (a logistics object URI, an embedded object id,
15 * or a blank node label `_:b0` for an object this change introduces).
16 */
17final readonly class OperationObject
18{
19    public function __construct(
20        public string $datatype,
21        public string $value,
22    ) {}
23
24    /**
25     * @throws ChangeException for a language-tagged literal: api:hasDatatype/api:hasValue cannot carry the tag
26     *                         (spec question 29), and writing it as xsd:string would silently change the value
27     */
28    public static function literal(Literal $literal): self
29    {
30        if ($literal->language !== null) {
31            throw ChangeException::because('Invalid resource', \sprintf('"%s"@%s is a language-tagged literal; an api:Change cannot express the language tag, so the value cannot be added or deleted through a change.', $literal->lexical, $literal->language));
32        }
33
34        return new self($literal->datatype, $literal->lexical);
35    }
36
37    public function isLiteral(): bool
38    {
39        return str_starts_with($this->datatype, Namespaces::XSD);
40    }
41
42    public function isBlankNode(): bool
43    {
44        return !$this->isLiteral() && str_starts_with($this->value, '_:');
45    }
46
47    public function toLiteral(): Literal
48    {
49        if (!$this->isLiteral()) {
50            throw new LogicException('Not a literal operation object.');
51        }
52
53        return new Literal($this->value, $this->datatype);
54    }
55}