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.
Completed
Push — develop ( 5fe34b...11f42d )
by Baptiste
03:53
created

Map::of()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 9
cts 9
cp 1
rs 9.3142
c 0
b 0
f 0
cc 3
eloc 14
nc 3
nop 4
crap 3
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Immutable;
5
6
use Innmind\Immutable\{
7
    Exception\InvalidArgumentException,
8
    Exception\LogicException,
9
    Exception\ElementNotFoundException,
10
    Exception\GroupEmptyMapException
11
};
12
13
final class Map implements MapInterface
14
{
15
    use Type;
16
17
    private $keyType;
18
    private $valueType;
19
    private $keySpecification;
20
    private $valueSpecification;
21
    private $keys;
22
    private $values;
23
    private $pairs;
24
25
    /**
26
     * {@inheritdoc}
27
     */
28 123
    public function __construct(string $keyType, string $valueType)
29
    {
30 123
        $this->keySpecification = $this->getSpecificationFor($keyType);
31 123
        $this->valueSpecification = $this->getSpecificationFor($valueType);
32 123
        $this->keyType = new Str($keyType);
33 123
        $this->valueType = new Str($valueType);
34 123
        $this->keys = new Stream($keyType);
35 123
        $this->values = new Stream($valueType);
36 123
        $this->pairs = new Stream(Pair::class);
37 123
    }
38
39 6
    public static function of(
40
        string $key,
41
        string $value,
42
        array $keys,
43
        array $values
44
    ): self {
45 6
        $keys = array_values($keys);
46 6
        $values = array_values($values);
47
48 6
        if (count($keys) !== count($values)) {
49 3
            throw new LogicException('Different sizes of keys and values');
50
        }
51
52 3
        $self = new self($key, $value);
53
54 3
        foreach ($keys as $i => $key) {
55 3
            $self = $self->put($key, $values[$i]);
56
        }
57
58 3
        return $self;
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64 51
    public function keyType(): Str
65
    {
66 51
        return $this->keyType;
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 48
    public function valueType(): Str
73
    {
74 48
        return $this->valueType;
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80 24
    public function size(): int
81
    {
82 24
        return $this->keys->size();
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 9
    public function count(): int
89
    {
90 9
        return $this->keys->count();
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96 3
    public function current()
97
    {
98 3
        return $this->values->current();
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104 3
    public function key()
105
    {
106 3
        return $this->keys->current();
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112 3
    public function next()
113
    {
114 3
        $this->keys->next();
115 3
        $this->values->next();
116 3
        $this->pairs->next();
117 3
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122 3
    public function rewind()
123
    {
124 3
        $this->keys->rewind();
125 3
        $this->values->rewind();
126 3
        $this->pairs->rewind();
127 3
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132 3
    public function valid()
133
    {
134 3
        return $this->keys->valid();
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140 3
    public function offsetExists($offset): bool
141
    {
142 3
        return $this->keys->contains($offset);
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148 12
    public function offsetGet($offset)
149
    {
150 12
        return $this->get($offset);
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156 3
    public function offsetSet($offset, $value)
157
    {
158 3
        throw new LogicException('You can\'t modify a map');
159
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164 3
    public function offsetUnset($offset)
165
    {
166 3
        throw new LogicException('You can\'t modify a map');
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172 102
    public function put($key, $value): MapInterface
173
    {
174 102
        $this->keySpecification->validate($key);
175 99
        $this->valueSpecification->validate($value);
176
177 93
        $map = clone $this;
178
179 93
        if ($this->keys->contains($key)) {
180 21
            $index = $this->keys->indexOf($key);
181 21
            $map->values = (new Stream((string) $this->valueType))
182 21
                ->append($this->values->take($index))
183 21
                ->add($value)
184 21
                ->append($this->values->drop($index + 1));
185 21
            $map->pairs = (new Stream(Pair::class))
186 21
                ->append($this->pairs->take($index))
187 21
                ->add(new Pair($key, $value))
188 21
                ->append($this->pairs->drop($index + 1));
189
        } else {
190 93
            $map->keys = $this->keys->add($key);
191 93
            $map->values = $this->values->add($value);
192 93
            $map->pairs = $this->pairs->add(new Pair($key, $value));
193
        }
194
195 93
        return $map;
196
    }
197
198
    /**
199
     * {@inheritdoc}
200
     */
201 48
    public function get($key)
202
    {
203 48
        if (!$this->keys->contains($key)) {
204 6
            throw new ElementNotFoundException;
205
        }
206
207 42
        return $this->values->get(
208 42
            $this->keys->indexOf($key)
209
        );
210
    }
211
212
    /**
213
     * {@inheritdoc}
214
     */
215 21
    public function contains($key): bool
216
    {
217 21
        return $this->keys->contains($key);
218
    }
219
220
    /**
221
     * {@inheritdoc}
222
     */
223 21
    public function clear(): MapInterface
224
    {
225 21
        $map = clone $this;
226 21
        $map->keys = new Stream((string) $this->keyType);
227 21
        $map->values = new Stream((string) $this->valueType);
228 21
        $map->pairs = new Stream(Pair::class);
229
230 21
        return $map;
231
    }
232
233
    /**
234
     * {@inheritdoc}
235
     */
236 9
    public function equals(MapInterface $map): bool
237
    {
238 9
        if (!$map->keys()->equals($this->keys())) {
0 ignored issues
show
Documentation introduced by
$this->keys() is of type object<Innmind\Immutable\SetInterface>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
239 6
            return false;
240
        }
241
242 6
        return $map->values()->equals($this->values());
0 ignored issues
show
Documentation introduced by
$this->values() is of type object<Innmind\Immutable\StreamInterface>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
243
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248 3
    public function filter(callable $predicate): MapInterface
249
    {
250 3
        $map = $this->clear();
251
252 3
        foreach ($this->pairs as $pair) {
253 3
            if ($predicate($pair->key(), $pair->value()) === true) {
254 3
                $map->keys = $map->keys->add($pair->key());
255 3
                $map->values = $map->values->add($pair->value());
256 3
                $map->pairs = $map->pairs->add($pair);
257
            }
258
        }
259
260 3
        return $map;
261
    }
262
263
    /**
264
     * {@inheritdoc}
265
     */
266 3
    public function foreach(callable $function): MapInterface
267
    {
268 3
        foreach ($this->pairs as $pair) {
269 3
            $function($pair->key(), $pair->value());
270
        }
271
272 3
        return $this;
273
    }
274
275
    /**
276
     * {@inheritdoc}
277
     */
278 6
    public function groupBy(callable $discriminator): MapInterface
279
    {
280 6
        if ($this->size() === 0) {
281 3
            throw new GroupEmptyMapException;
282
        }
283
284 3
        $map = null;
285
286 3
        foreach ($this->pairs as $pair) {
287 3
            $key = $discriminator($pair->key(), $pair->value());
288
289 3
            if ($map === null) {
290 3
                $map = new self(
291 3
                    $this->determineType($key),
292 3
                    MapInterface::class
293
                );
294
            }
295
296 3
            if ($map->contains($key)) {
297 3
                $map = $map->put(
298 3
                    $key,
299 3
                    $map->get($key)->put(
300 3
                        $pair->key(),
301 3
                        $pair->value()
302
                    )
303
                );
304
            } else {
305 3
                $map = $map->put(
306 3
                    $key,
307 3
                    $this->clear()->put(
308 3
                        $pair->key(),
309 3
                        $pair->value()
310
                    )
311
                );
312
            }
313
        }
314
315 3
        return $map;
316
    }
317
318
    /**
319
     * {@inheritdoc}
320
     */
321 30
    public function keys(): SetInterface
322
    {
323
        return $this
324 30
            ->keys
325 30
            ->reduce(
326 30
                new Set((string) $this->keyType),
327 30
                function(Set $carry, $key): Set {
328 30
                    return $carry->add($key);
329 30
                }
330
            );
331
    }
332
333
    /**
334
     * {@inheritdoc}
335
     */
336 24
    public function values(): StreamInterface
337
    {
338
        return $this
339 24
            ->values
340 24
            ->reduce(
341 24
                new Stream((string) $this->valueType),
342 24
                function(Stream $carry, $value): Stream {
343 24
                    return $carry->add($value);
344 24
                }
345
            );
346
    }
347
348
    /**
349
     * {@inheritdoc}
350
     */
351 9
    public function map(callable $function): MapInterface
352
    {
353 9
        $map = $this->clear();
354
355 9
        foreach ($this->pairs as $pair) {
356 9
            $return = $function(
357 9
                $pair->key(),
358 9
                $pair->value()
359
            );
360
361 9
            if ($return instanceof Pair) {
362 6
                $key = $return->key();
363 6
                $value = $return->value();
364
            } else {
365 6
                $key = $pair->key();
366 6
                $value = $return;
367
            }
368
369 9
            $map = $map->put($key, $value);
370
        }
371
372 3
        return $map;
373
    }
374
375
    /**
376
     * {@inheritdoc}
377
     */
378 3
    public function join(string $separator): Str
379
    {
380 3
        return $this->values->join($separator);
381
    }
382
383
    /**
384
     * {@inheritdoc}
385
     */
386 3
    public function remove($key): MapInterface
387
    {
388 3
        if (!$this->contains($key)) {
389 3
            return $this;
390
        }
391
392 3
        $index = $this->keys->indexOf($key);
393 3
        $map = clone $this;
394 3
        $map->keys = $this
395 3
            ->keys
396 3
            ->slice(0, $index)
397 3
            ->append($this->keys->slice($index + 1, $this->keys->size()));
398 3
        $map->values = $this
399 3
            ->values
400 3
            ->slice(0, $index)
401 3
            ->append($this->values->slice($index + 1, $this->values->size()));
402 3
        $map->pairs = $this
403 3
            ->pairs
404 3
            ->slice(0, $index)
405 3
            ->append($this->pairs->slice($index + 1, $this->pairs->size()));
406
407 3
        return $map;
408
    }
409
410
    /**
411
     * {@inheritdoc}
412
     */
413 6
    public function merge(MapInterface $map): MapInterface
414
    {
415
        if (
416 6
            !$this->keyType()->equals($map->keyType()) ||
0 ignored issues
show
Documentation introduced by
$map->keyType() is of type object<Innmind\Immutable\Str>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
417 6
            !$this->valueType()->equals($map->valueType())
0 ignored issues
show
Documentation introduced by
$map->valueType() is of type object<Innmind\Immutable\Str>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
418
        ) {
419 3
            throw new InvalidArgumentException(
420 3
                'The 2 maps does not reference the same types'
421
            );
422
        }
423
424 3
        return $map->reduce(
425 3
            $this,
426 3
            function(self $carry, $key, $value): self {
427 3
                return $carry->put($key, $value);
428 3
            }
429
        );
430
    }
431
432
    /**
433
     * {@inheritdoc}
434
     */
435 3
    public function partition(callable $predicate): MapInterface
436
    {
437 3
        $truthy = $this->clear();
438 3
        $falsy = $this->clear();
439
440 3
        foreach ($this->pairs as $pair) {
441 3
            $return = $predicate(
442 3
                $pair->key(),
443 3
                $pair->value()
444
            );
445
446 3
            if ($return === true) {
447 3
                $truthy = $truthy->put($pair->key(), $pair->value());
448
            } else {
449 3
                $falsy = $falsy->put($pair->key(), $pair->value());
450
            }
451
        }
452
453 3
        return (new self('bool', MapInterface::class))
454 3
            ->put(true, $truthy)
455 3
            ->put(false, $falsy);
456
    }
457
458
    /**
459
     * {@inheritdoc}
460
     */
461 9
    public function reduce($carry, callable $reducer)
462
    {
463 9
        foreach ($this->pairs as $pair) {
464 9
            $carry = $reducer($carry, $pair->key(), $pair->value());
465
        }
466
467 9
        return $carry;
468
    }
469
}
470