Passed
Push — master ( a5b230...855b1b )
by Mr
06:47
created

Map::assertValidMap()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the daikon-cqrs/data-structure 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\DataStructure;
10
11
use Daikon\Interop\Assert;
12
use Daikon\Interop\Assertion;
13
use Ds\Map as DsMap;
14
15
abstract class Map implements MapInterface
16
{
17
    protected DsMap $compositeMap;
18
19 25
    protected function init(iterable $values): void
20
    {
21 25
        Assertion::false(isset($this->compositeMap), 'Cannot reinitialize map.');
22
23 25
        foreach ($values as $key => $value) {
24 24
            $this->assertValidKey($key);
25 23
            $this->assertValidType($value);
26
        }
27
28 23
        $this->compositeMap = new DsMap($values);
29 23
    }
30
31
    /** @return static */
32 1
    public function empty(): self
33
    {
34 1
        $this->assertInitialized();
35 1
        $copy = clone $this;
36 1
        $copy->compositeMap->clear();
37 1
        return $copy;
38
    }
39
40 1
    public function keys(): array
41
    {
42 1
        $this->assertInitialized();
43 1
        return $this->compositeMap->keys()->toArray();
44
    }
45
46 7
    public function has(string $key): bool
47
    {
48 7
        $this->assertInitialized();
49 7
        return $this->compositeMap->hasKey($key);
50
    }
51
52 7
    public function get(string $key, $default = null)
53
    {
54 7
        $this->assertInitialized();
55 7
        if (func_num_args() === 1) {
56 4
            Assertion::satisfy($key, [$this, 'has'], "Key '$key' not found and no default provided.");
57 2
            return $this->compositeMap->get($key);
58
        } else {
59 3
            if (!is_null($default)) {
60 2
                $this->assertValidType($default);
61
            }
62 2
            return $this->compositeMap->get($key, $default);
63
        }
64
    }
65
66
    /** @return static */
67 2
    public function with(string $key, $value): self
68
    {
69 2
        $this->assertInitialized();
70 2
        $this->assertValidType($value);
71 1
        $copy = clone $this;
72 1
        $copy->compositeMap->put($key, $value);
73 1
        return $copy;
74
    }
75
76
    /** @return static */
77 2
    public function without(string $key): self
78
    {
79 2
        $this->assertInitialized();
80 2
        Assertion::satisfy($key, [$this, 'has'], "Key '$key' not found.");
81 1
        $copy = clone $this;
82 1
        $copy->compositeMap->remove($key);
83 1
        return $copy;
84
    }
85
86 1
    public function first()
87
    {
88 1
        $this->assertInitialized();
89
        /** @psalm-suppress MissingPropertyType */
90 1
        return $this->compositeMap->first()->value;
91
    }
92
93 1
    public function last()
94
    {
95 1
        $this->assertInitialized();
96
        /** @psalm-suppress MissingPropertyType */
97 1
        return $this->compositeMap->last()->value;
98
    }
99
100 2
    public function isEmpty(): bool
101
    {
102 2
        $this->assertInitialized();
103 2
        return $this->compositeMap->isEmpty();
104
    }
105
106
    /** @param static $comparator */
107 1
    public function equals($comparator): bool
108
    {
109 1
        $this->assertValidMap($comparator);
110 1
        return $this->unwrap() === $comparator->unwrap();
111
    }
112
113 3
    public function count(): int
114
    {
115 3
        $this->assertInitialized();
116 3
        return $this->compositeMap->count();
117
    }
118
119 6
    public function unwrap(): array
120
    {
121 6
        $this->assertInitialized();
122 6
        return $this->compositeMap->toArray();
123
    }
124
125
    /** @psalm-suppress ImplementedReturnTypeMismatch */
126 2
    public function getIterator(): DsMap
127
    {
128 2
        return $this->compositeMap;
129
    }
130
131 21
    protected function assertInitialized(): void
132
    {
133 21
        Assertion::true(isset($this->compositeMap), 'Map is not initialized.');
134 21
    }
135
136
    /** @param mixed $key */
137 24
    protected function assertValidKey($key): void
138
    {
139 24
        Assert::that($key, 'Key must be a valid string.')->string()->notEmpty();
140 23
    }
141
142
    /** @param mixed $value */
143 23
    protected function assertValidType($value): void
144
    {
145 23
        Assertion::true(
146 23
            is_array($value) || is_scalar($value),
147
            sprintf(
148 23
                "Invalid value type given to '%s', expected scalar or array but was given '%s'.",
149 23
                static::class,
150 23
                is_object($value) ? get_class($value) : @gettype($value)
151
            )
152
        );
153 22
    }
154
155
    /** @param mixed $map */
156 1
    protected function assertValidMap($map): void
157
    {
158 1
        Assertion::isInstanceOf(
159 1
            $map,
160 1
            static::class,
161 1
            sprintf("Map operation must be on same type as '%s'.", static::class)
162
        );
163 1
    }
164
165 2
    public function __get(string $key)
166
    {
167 2
        return $this->get($key);
168
    }
169
170 4
    public function __clone()
171
    {
172 4
        $this->compositeMap = clone $this->compositeMap;
173 4
    }
174
}
175