Passed
Push — master ( 5c1ecd...f2a4ef )
by Mr
01:54
created

Map::empty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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