Passed
Push — master ( 2dfc84...94e87c )
by Edward
05:17
created

RangeSet::loadUnsafe()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 6
rs 10
1
<?php
2
3
namespace Remorhaz\UniLex\RegExp\FSM;
4
5
use Remorhaz\UniLex\Exception;
6
7
class RangeSet
8
{
9
10
    /**
11
     * @var Range[]
12
     */
13
    private $rangeList = [];
14
15
    public static function loadUnsafe(Range ...$rangeList): self
16
    {
17
        $rangeSet = new self();
18
        $rangeSet->rangeList = $rangeList;
19
20
        return $rangeSet;
21
    }
22
23
    /**
24
     * RangeSet constructor.
25
     *
26
     * @param Range ...$rangeList
27
     * @throws Exception
28
     */
29
    public function __construct(Range ...$rangeList)
30
    {
31
        if (!empty($rangeList)) {
32
            $this->addRange(...$rangeList);
33
        }
34
    }
35
36
    /**
37
     * @param array ...$rangeDataList
38
     * @return RangeSet
39
     * @throws Exception
40
     */
41
    public static function import(array ...$rangeDataList): self
42
    {
43
        return new self(...Range::importList(...$rangeDataList));
44
    }
45
46
    public function export(): array
47
    {
48
        $rangeDataList = [];
49
        foreach ($this->getRanges() as $range) {
50
            $rangeDataList[] = $range->export();
51
        }
52
53
        return $rangeDataList;
54
    }
55
56
    /**
57
     * @param Range ...$rangeList
58
     * @throws Exception
59
     */
60
    public function addRange(Range ...$rangeList): void
61
    {
62
        foreach ($rangeList as $range) {
63
            $this->mergeSingleRange($range);
64
        }
65
    }
66
67
    /**
68
     * @return Range[]
69
     */
70
    public function getRanges(): array
71
    {
72
        return $this->rangeList;
73
    }
74
75
    public function isEmpty(): bool
76
    {
77
        return empty($this->rangeList);
78
    }
79
80
    /**
81
     * @param Range $range
82
     * @throws Exception
83
     */
84
    private function mergeSingleRange(Range $range): void
85
    {
86
        if (empty($this->rangeList)) {
87
            $this->rangeList = [$range];
88
89
            return;
90
        }
91
        $newRangeList = [];
92
        foreach ($this->rangeList as $existingRange) {
93
            if ($existingRange->containsStartOf($range) || $range->follows($existingRange)) {
94
                $range = $range->copyAfterStartOf($existingRange);
95
                continue;
96
            }
97
            if ($existingRange->containsFinishOf($range) || $existingRange->follows($range)) {
98
                $range = $range->copyBeforeFinishOf($existingRange);
99
                continue;
100
            }
101
            $newRangeList[] = $existingRange;
102
        }
103
        $newRangeList[] = $range;
104
        $this->setSortedRangeList(...$newRangeList);
105
    }
106
107
    private function setSortedRangeList(Range ...$rangeList): void
108
    {
109
        $sortByFrom = function (Range $rangeOne, Range $rangeTwo): int {
110
            return $rangeOne->getStart() <=> $rangeTwo->getStart();
111
        };
112
        usort($rangeList, $sortByFrom);
113
        $this->rangeList = $rangeList;
114
    }
115
}
116