Lines 100.00% 18 / 18
Methods 100.00% 7 / 7
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 replacingWith 100.00% 1 / 1 100.00% 1 / 1 1
 withAdded 100.00% 6 / 6 100.00% 1 / 1 2
 withRemoved 100.00% 6 / 6 100.00% 1 / 1 2
 needsCurrentLabels 100.00% 1 / 1 100.00% 1 / 1 1
 resolveAgainst 100.00% 1 / 1 100.00% 1 / 1 1
 applyTo 100.00% 2 / 2 100.00% 1 / 1 2
11final readonly class EntityLabelsChange
12{
13    /**
14     * @param list<LabelId>|null $replacement
15     * @param list<LabelId> $added
16     * @param list<LabelId> $removed
17     */
18    public function __construct(
19        #[ListOf(LabelId::class)]
20        public ?array $replacement = null,
21        #[ListOf(LabelId::class)]
22        public array $added = [],
23        #[ListOf(LabelId::class)]
24        public array $removed = [],
25    ) {}
26
27    public static function replacingWith(LabelIdCollection $labelIds): self
28    {
29        return new self($labelIds->listValues());
30    }
31
32    public function withAdded(LabelIdCollection $labelIds): self
33    {
34        if ($this->replacement !== null) {
35            return self::replacingWith(LabelIdCollection::fromList($this->replacement)->withAddedMembers($labelIds));
36        }
37
38        return new self(
39            added: LabelIdCollection::fromList($this->added)->withAddedMembers($labelIds)->listValues(),
40            removed: LabelIdCollection::fromList($this->removed)->withoutMembers($labelIds)->listValues(),
41        );
42    }
43
44    public function withRemoved(LabelIdCollection $labelIds): self
45    {
46        if ($this->replacement !== null) {
47            return self::replacingWith(LabelIdCollection::fromList($this->replacement)->withoutMembers($labelIds));
48        }
49
50        return new self(
51            added: LabelIdCollection::fromList($this->added)->withoutMembers($labelIds)->listValues(),
52            removed: LabelIdCollection::fromList($this->removed)->withAddedMembers($labelIds)->listValues(),
53        );
54    }
55
56    public function needsCurrentLabels(): bool
57    {
58        return $this->replacement === null;
59    }
60
61    public function resolveAgainst(LabelIdCollection $current): self
62    {
63        return self::replacingWith($this->applyTo($current));
64    }
65
66    public function applyTo(LabelIdCollection $current): LabelIdCollection
67    {
68        $base = $this->replacement === null ? $current : LabelIdCollection::fromList($this->replacement);
69
70        return $base->withAddedMembers(LabelIdCollection::fromList($this->added))->withoutMembers(LabelIdCollection::fromList($this->removed));
71    }
72}