Passed
Push — master ( 610227...7a4f69 )
by Mr
02:59
created

MapTrait::assertValidType()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

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