CommitSequence::__clone()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the daikon-cqrs/event-sourcing project.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Daikon\EventSourcing\EventStore\Commit;
10
11
use Daikon\EventSourcing\EventStore\Stream\Sequence;
12
use Daikon\Interop\RuntimeException;
13
use Ds\Vector;
14
15
final class CommitSequence implements CommitSequenceInterface
16
{
17
    private Vector $compositeVector;
18
19
    /** @param array $commits */
20
    public static function fromNative($commits): self
21
    {
22
        return new self(array_map(
23
            fn(array $state): CommitInterface => Commit::fromNative($state),
24
            $commits
25
        ));
26
    }
27
28 2
    public static function makeEmpty(): self
29
    {
30 2
        return new self;
31
    }
32
33 2
    public function __construct(iterable $commits = [])
34
    {
35 2
        $this->compositeVector = (
36 2
            fn(CommitInterface ...$commits): Vector => new Vector($commits)
37
        )(...$commits);
38 2
    }
39
40
    public function push(CommitInterface $commit): self
41
    {
42
        if (!$this->isEmpty()) {
43
            $nextRevision = $this->getHead()->getHeadRevision()->increment();
44
            if (!$nextRevision->equals($commit->getTailRevision())) {
45
                throw new RuntimeException(sprintf(
46
                    'Trying to add invalid revision %s to event-sequence, expected revision is %s.',
47
                    (string)$commit->getHeadRevision(),
48
                    (string)$nextRevision
49
                ));
50
            }
51
        }
52
        $commitSequence = clone $this;
53
        $commitSequence->compositeVector->push($commit);
54
        return $commitSequence;
55
    }
56
57 1
    public function toNative(): array
58
    {
59 1
        $nativeList = [];
60 1
        foreach ($this as $commit) {
61
            $nativeRep = $commit->toNative();
62
            $nativeRep['@type'] = get_class($commit);
63
            $nativeList[] = $nativeRep;
64
        }
65 1
        return $nativeList;
66
    }
67
68
    public function getTail(): CommitInterface
69
    {
70
        return $this->compositeVector->first();
71
    }
72
73
    public function getHead(): CommitInterface
74
    {
75
        return $this->compositeVector->last();
76
    }
77
78 1
    public function has(Sequence $sequence): bool
79
    {
80 1
        $offset = $sequence->toNative() - 1;
81 1
        return isset($this->compositeVector->{$offset});
82
    }
83
84
    public function get(Sequence $sequence): CommitInterface
85
    {
86
        $offset = $sequence->toNative() - 1;
87
        return $this->compositeVector->get($offset);
88
    }
89
90
    public function getSlice(Sequence $start, Sequence $end): self
91
    {
92
        /** @psalm-suppress InvalidArgument */
93
        return $this->compositeVector->reduce(
94
            function (CommitSequenceInterface $commits, CommitInterface $commit) use ($start, $end): self {
95
                if ($commit->getSequence()->isWithinRange($start, $end)) {
96
                    $commits = $commits->push($commit);
97
                }
98
                return $commits;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $commits returns the type Daikon\EventSourcing\Eve...CommitSequenceInterface which includes types incompatible with the type-hinted return Daikon\EventSourcing\Eve...e\Commit\CommitSequence.
Loading history...
99
            },
100
            new self
101
        );
102
    }
103
104
    public function isEmpty(): bool
105
    {
106
        return $this->compositeVector->isEmpty();
107
    }
108
109
    public function revisionOf(CommitInterface $commit): Sequence
110
    {
111
        $revision = $this->compositeVector->find($commit);
112
        if (is_bool($revision)) {
113
            return Sequence::makeInitial();
114
        }
115
        return Sequence::fromNative($revision);
116
    }
117
118
    public function count(): int
119
    {
120
        return $this->compositeVector->count();
121
    }
122
123 1
    public function getIterator(): Vector
124
    {
125 1
        return $this->compositeVector;
126
    }
127
128
    private function __clone()
129
    {
130
        $this->compositeVector = clone $this->compositeVector;
131
    }
132
}
133