GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — develop ( c3b70c...588978 )
by Baptiste
05:12
created

Primitive::merge()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 9
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 15
ccs 8
cts 8
cp 1
crap 3
rs 9.9666
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Immutable\Map;
5
6
use Innmind\Immutable\{
7
    Map,
8
    Type,
9
    Str,
10
    Stream,
11
    Set,
12
    Pair,
13
    SpecificationInterface,
14
    Exception\InvalidArgumentException,
15
    Exception\LogicException,
16
    Exception\ElementNotFoundException,
17
    Exception\GroupEmptyMapException
18
};
19
20
/**
21
 * {@inheritdoc}
22
 */
23
final class Primitive implements Implementation
24
{
25
    private string $keyType;
26
    private string $valueType;
27
    private SpecificationInterface $keySpecification;
28
    private SpecificationInterface $valueSpecification;
29
    private array $values;
30
    private ?int $size;
31
32
    /**
33
     * {@inheritdoc}
34
     */
35 64
    public function __construct(string $keyType, string $valueType)
36
    {
37 64
        $this->keySpecification = Type::of($keyType);
38
39 64
        if (!in_array($keyType, ['int', 'integer', 'string'], true)) {
40 1
            throw new LogicException;
41
        }
42
43 63
        $this->valueSpecification = Type::of($valueType);
44 63
        $this->keyType = $keyType;
45 63
        $this->valueType = $valueType;
46 63
        $this->values = [];
47 63
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52 22
    public function keyType(): string
53
    {
54 22
        return $this->keyType;
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60 20
    public function valueType(): string
61
    {
62 20
        return $this->valueType;
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68 20
    public function size(): int
69
    {
70 20
        return $this->size ?? $this->size = \count($this->values);
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76 1
    public function count(): int
77
    {
78 1
        return $this->size();
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84 52
    public function put($key, $value): Implementation
85
    {
86 52
        $this->keySpecification->validate($key);
87 50
        $this->valueSpecification->validate($value);
88
89 46
        $map = clone $this;
90 46
        $map->size = null;
91 46
        $map->values[$key] = $value;
92 46
        \reset($map->values);
93
94 46
        return $map;
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100 21
    public function get($key)
101
    {
102 21
        if (!$this->contains($key)) {
103 2
            throw new ElementNotFoundException;
104
        }
105
106 19
        return $this->values[$key];
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112 26
    public function contains($key): bool
113
    {
114 26
        return \array_key_exists($key, $this->values);
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120 10
    public function clear(): Implementation
121
    {
122 10
        $map = clone $this;
123 10
        $map->size = null;
124 10
        $map->values = [];
125
126 10
        return $map;
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132 7
    public function equals(Implementation $map): bool
133
    {
134 7
        if ($map->size() !== $this->size()) {
135 2
            return false;
136
        }
137
138 7
        foreach ($this->values as $k => $v) {
139 6
            if (!$map->contains($k)) {
140 2
                return false;
141
            }
142
143 6
            if ($map->get($k) !== $v) {
144 3
                return false;
145
            }
146
        }
147
148 6
        return true;
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154 2
    public function filter(callable $predicate): Implementation
155
    {
156 2
        $map = $this->clear();
157
158 2
        foreach ($this->values as $k => $v) {
159 2
            if ($predicate($this->normalizeKey($k), $v) === true) {
160 2
                $map->values[$k] = $v;
161
            }
162
        }
163
164 2
        \reset($map->values);
165
166 2
        return $map;
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172 3
    public function foreach(callable $function): void
173
    {
174 3
        foreach ($this->values as $k => $v) {
175 3
            $function($this->normalizeKey($k), $v);
176
        }
177 3
    }
178
179
    /**
180
     * {@inheritdoc}
181
     */
182 4
    public function groupBy(callable $discriminator): Map
183
    {
184 4
        if ($this->size() === 0) {
185 2
            throw new GroupEmptyMapException;
186
        }
187
188 2
        $map = null;
189
190 2
        foreach ($this->values as $k => $v) {
191 2
            $key = $discriminator($this->normalizeKey($k), $v);
192
193 2
            if ($map === null) {
194 2
                $map = new Map(
195 2
                    Type::determine($key),
196 2
                    Map::class
197
                );
198
            }
199
200 2
            if ($map->contains($key)) {
201 2
                $map = $map->put(
202 2
                    $key,
203 2
                    $map->get($key)->put($k, $v)
204
                );
205
            } else {
206 2
                $map = $map->put(
207 2
                    $key,
208 2
                    $this->clearMap()->put($k, $v)
209
                );
210
            }
211
        }
212
213 2
        return $map;
1 ignored issue
show
Bug Best Practice introduced by
The expression return $map could return the type null which is incompatible with the type-hinted return Innmind\Immutable\Map. Consider adding an additional type-check to rule them out.
Loading history...
214
    }
215
216
    /**
217
     * {@inheritdoc}
218
     */
219 15
    public function keys(): Set
220
    {
221 15
        return Set::of(
222 15
            $this->keyType,
223
            ...\array_map(function($key) {
224 15
                return $this->normalizeKey($key);
225 15
            }, \array_keys($this->values))
226
        );
227
    }
228
229
    /**
230
     * {@inheritdoc}
231
     */
232 14
    public function values(): Stream
233
    {
234 14
        return Stream::of($this->valueType, ...\array_values($this->values));
235
    }
236
237
    /**
238
     * {@inheritdoc}
239
     */
240 6
    public function map(callable $function): Implementation
241
    {
242 6
        $map = $this->clear();
243
244 6
        foreach ($this->values as $k => $v) {
245 6
            $return = $function($this->normalizeKey($k), $v);
246
247 6
            if ($return instanceof Pair) {
248 4
                $this->keySpecification->validate($return->key());
249
250 2
                $key = $return->key();
251 2
                $value = $return->value();
252
            } else {
253 4
                $key = $k;
254 4
                $value = $return;
255
            }
256
257 4
            $this->valueSpecification->validate($value);
258
259 2
            $map->values[$key] = $value;
260
        }
261
262 2
        \reset($map->values);
263
264 2
        return $map;
265
    }
266
267
    /**
268
     * {@inheritdoc}
269
     */
270 2
    public function join(string $separator): Str
271
    {
272 2
        return $this->values()->join($separator);
273
    }
274
275
    /**
276
     * {@inheritdoc}
277
     */
278 2
    public function remove($key): Implementation
279
    {
280 2
        if (!$this->contains($key)) {
281 2
            return $this;
282
        }
283
284 2
        $map = clone $this;
285 2
        $map->size = null;
286 2
        unset($map->values[$key]);
287 2
        \reset($map->values);
288
289 2
        return $map;
290
    }
291
292
    /**
293
     * {@inheritdoc}
294
     */
295 3
    public function merge(Implementation $map): Implementation
296
    {
297
        if (
298 3
            $this->keyType !== $map->keyType() ||
299 3
            $this->valueType !== $map->valueType()
300
        ) {
301 2
            throw new InvalidArgumentException(
302 2
                'The 2 maps does not reference the same types'
303
            );
304
        }
305
306 1
        return $map->reduce(
307 1
            $this,
308
            function(self $carry, $key, $value): self {
309 1
                return $carry->put($key, $value);
310 1
            }
311
        );
312
    }
313
314
    /**
315
     * {@inheritdoc}
316
     */
317 2
    public function partition(callable $predicate): Map
318
    {
319 2
        $truthy = $this->clearMap();
320 2
        $falsy = $this->clearMap();
321
322 2
        foreach ($this->values as $k => $v) {
323 2
            $return = $predicate($this->normalizeKey($k), $v);
324
325 2
            if ($return === true) {
326 2
                $truthy = $truthy->put($k, $v);
327
            } else {
328 2
                $falsy = $falsy->put($k, $v);
329
            }
330
        }
331
332 2
        return Map::of('bool', Map::class)
333 2
            (true, $truthy)
334 2
            (false, $falsy);
335
    }
336
337
    /**
338
     * {@inheritdoc}
339
     */
340 4
    public function reduce($carry, callable $reducer)
341
    {
342 4
        foreach ($this->values as $k => $v) {
343 4
            $carry = $reducer($carry, $this->normalizeKey($k), $v);
344
        }
345
346 4
        return $carry;
347
    }
348
349 1
    public function empty(): bool
350
    {
351 1
        \reset($this->values);
352
353 1
        return \is_null(\key($this->values));
354
    }
355
356 25
    private function normalizeKey($value)
357
    {
358 25
        if ($this->keyType === 'string' && !\is_null($value)) {
359 1
            return (string) $value;
360
        }
361
362 24
        return $value;
363
    }
364
365
    /**
366
     * @return Map<T, S>
367
     */
368 4
    private function clearMap(): Map
369
    {
370 4
        return Map::of($this->keyType, $this->valueType);
371
    }
372
}
373