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 ( a1e45f...4cf84e )
by Baptiste
05:27
created

DoubleIndex::toSetOf()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 5
c 0
b 0
f 0
nc 3
nop 2
dl 0
loc 12
ccs 6
cts 6
cp 1
crap 3
rs 10
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
    Sequence,
11
    Set,
12
    Pair,
13
    ValidateArgument,
14
    Exception\LogicException,
15
    Exception\ElementNotFound,
16
    Exception\CannotGroupEmptyStructure,
17
};
18
use function Innmind\Immutable\unwrap;
19
20
/**
21
 * @template T
22
 * @template S
23
 */
24
final class DoubleIndex implements Implementation
25
{
26
    private string $keyType;
27
    private string $valueType;
28
    private ValidateArgument $validateKey;
29
    private ValidateArgument $validateValue;
30
    /** @var Sequence<T> */
31
    private Sequence $keys;
32
    /** @var Sequence<S> */
33
    private Sequence $values;
34
    /** @var Sequence<Pair<T, S>> */
35
    private Sequence $pairs;
36
37 71
    public function __construct(string $keyType, string $valueType)
38
    {
39 71
        $this->validateKey = Type::of($keyType);
40 71
        $this->validateValue = Type::of($valueType);
41 71
        $this->keyType = $keyType;
42 71
        $this->valueType = $valueType;
43 71
        $this->keys = Sequence::of($keyType);
44 71
        $this->values = Sequence::of($valueType);
45
        /** @var Sequence<Pair<T, S>> */
46 71
        $this->pairs = Sequence::of(Pair::class);
0 ignored issues
show
Bug introduced by
The property pairs does not seem to exist on Innmind\Immutable\Sequence.
Loading history...
47 71
    }
48
49 16
    public function keyType(): string
50
    {
51 16
        return $this->keyType;
52
    }
53
54 16
    public function valueType(): string
55
    {
56 16
        return $this->valueType;
57
    }
58
59 4
    public function size(): int
60
    {
61 4
        return $this->keys->size();
62
    }
63
64 4
    public function count(): int
65
    {
66 4
        return $this->keys->count();
67
    }
68
69
    /**
70
     * @param T $key
0 ignored issues
show
Bug introduced by
The type Innmind\Immutable\Map\T was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
71
     * @param S $value
0 ignored issues
show
Bug introduced by
The type Innmind\Immutable\Map\S was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
72
     *
73
     * @return self<T, S>
74
     */
75 32
    public function put($key, $value): self
76
    {
77 32
        ($this->validateKey)($key, 1);
78 31
        ($this->validateValue)($value, 2);
79
80 30
        $map = clone $this;
81
82 30
        if ($this->keys->contains($key)) {
83 3
            $index = $this->keys->indexOf($key);
84 3
            $map->values = $this->values->take($index)
85 3
                ->add($value)
86 3
                ->append($this->values->drop($index + 1));
87
            /** @var Sequence<Pair<T, S>> */
88 3
            $map->pairs = $this->pairs->take($index)
0 ignored issues
show
Bug introduced by
The property pairs does not seem to exist on Innmind\Immutable\Sequence.
Loading history...
89 3
                ->add(new Pair($key, $value))
90 3
                ->append($this->pairs->drop($index + 1));
91
        } else {
92
            /** @var Sequence<T> */
93 30
            $map->keys = ($this->keys)($key);
0 ignored issues
show
Bug introduced by
The property keys does not seem to exist on Innmind\Immutable\Sequence.
Loading history...
94 30
            $map->values = ($this->values)($value);
95
            /** @var Sequence<Pair<T, S>> */
96 30
            $map->pairs = ($this->pairs)(new Pair($key, $value));
97
        }
98
99 30
        return $map;
100
    }
101
102
    /**
103
     * @param T $key
104
     *
105
     * @throws ElementNotFound
106
     *
107
     * @return S
108
     */
109 16
    public function get($key)
110
    {
111 16
        if (!$this->keys->contains($key)) {
112 1
            throw new ElementNotFound($key);
113
        }
114
115 15
        return $this->values->get(
116 15
            $this->keys->indexOf($key)
117
        );
118
    }
119
120
    /**
121
     * @param T $key
122
     */
123 3
    public function contains($key): bool
124
    {
125 3
        return $this->keys->contains($key);
126
    }
127
128
    /**
129
     * @return self<T, S>
130
     */
131 5
    public function clear(): self
132
    {
133 5
        $map = clone $this;
134 5
        $map->keys = $this->keys->clear();
135 5
        $map->values = $this->values->clear();
136 5
        $map->pairs = $this->pairs->clear();
137
138 5
        return $map;
139
    }
140
141
    /**
142
     * @param Implementation<T, S> $map
143
     */
144 2
    public function equals(Implementation $map): bool
145
    {
146 2
        if (!$map->keys()->equals($this->keys())) {
147 1
            return false;
148
        }
149
150 2
        foreach ($this->pairs->toArray() as $pair) {
151 2
            if ($map->get($pair->key()) !== $pair->value()) {
152 2
                return false;
153
            }
154
        }
155
156 1
        return true;
157
    }
158
159
    /**
160
     * @param callable(T, S): bool $predicate
161
     *
162
     * @return self<T, S>
163
     */
164 1
    public function filter(callable $predicate): self
165
    {
166 1
        $map = $this->clear();
167
168 1
        foreach ($this->pairs->toArray() as $pair) {
169 1
            if ($predicate($pair->key(), $pair->value()) === true) {
170
                /** @psalm-suppress MixedArgumentTypeCoercion */
171 1
                $map->keys = ($map->keys)($pair->key());
172
                /** @psalm-suppress MixedArgumentTypeCoercion */
173 1
                $map->values = ($map->values)($pair->value());
174
                /**
175
                 * @psalm-suppress MixedArgumentTypeCoercion
176
                 * @var Sequence<Pair<T, S>>
177
                 */
178 1
                $map->pairs = ($map->pairs)($pair);
179
            }
180
        }
181
182 1
        return $map;
183
    }
184
185
    /**
186
     * @param callable(T, S): void $function
187
     */
188 1
    public function foreach(callable $function): void
189
    {
190 1
        foreach ($this->pairs->toArray() as $pair) {
191 1
            $function($pair->key(), $pair->value());
192
        }
193 1
    }
194
195
    /**
196
     * @template D
197
     * @param callable(T, S): D $discriminator
198
     *
199
     * @throws CannotGroupEmptyStructure
200
     *
201
     * @return Map<D, Map<T, S>>
202
     */
203 2
    public function groupBy(callable $discriminator): Map
204
    {
205 2
        if ($this->empty()) {
206 1
            throw new CannotGroupEmptyStructure;
207
        }
208
209 1
        $groups = null;
210
211 1
        foreach ($this->pairs->toArray() as $pair) {
212 1
            $key = $discriminator($pair->key(), $pair->value());
213
214 1
            if ($groups === null) {
215
                /** @var Map<D, Map<T, S>> */
216 1
                $groups = Map::of(
217 1
                    Type::determine($key),
218 1
                    Map::class,
219
                );
220
            }
221
222 1
            if ($groups->contains($key)) {
223
                /** @var Map<T, S> */
224 1
                $group = $groups->get($key);
225
                /** @var Map<T, S> */
226 1
                $group = ($group)($pair->key(), $pair->value());
227
228 1
                $groups = ($groups)($key, $group);
229
            } else {
230
                /** @var Map<T, S> */
231 1
                $group = $this->clearMap()($pair->key(), $pair->value());
232
233 1
                $groups = ($groups)($key, $group);
234
            }
235
        }
236
237
        /** @var Map<D, Map<T, S>> */
238 1
        return $groups;
239
    }
240
241
    /**
242
     * @return Set<T>
243
     */
244 10
    public function keys(): Set
245
    {
246 10
        return Set::of($this->keyType, ...$this->keys->toArray());
247
    }
248
249
    /**
250
     * @return Sequence<S>
251
     */
252 5
    public function values(): Sequence
253
    {
254 5
        return $this->values;
255
    }
256
257
    /**
258
     * @param callable(T, S): (S|Pair<T, S>) $function
259
     *
260
     * @return self<T, S>
261
     */
262 3
    public function map(callable $function): self
263
    {
264 3
        $map = $this->clear();
265
266 3
        foreach ($this->pairs->toArray() as $pair) {
267 3
            $return = $function($pair->key(), $pair->value());
268
269 3
            if ($return instanceof Pair) {
270
                /** @var T */
271 2
                $key = $return->key();
272
                /** @var S */
273 2
                $value = $return->value();
274
            } else {
275 2
                $key = $pair->key();
276 2
                $value = $return;
277
            }
278
279 3
            $map = $map->put($key, $value);
280
        }
281
282 1
        return $map;
283
    }
284
285 1
    public function join(string $separator): Str
286
    {
287 1
        return $this->values->join($separator);
288
    }
289
290
    /**
291
     * @param T $key
292
     *
293
     * @return self<T, S>
294
     */
295 1
    public function remove($key): Implementation
296
    {
297 1
        if (!$this->contains($key)) {
298 1
            return $this;
299
        }
300
301 1
        $index = $this->keys->indexOf($key);
302 1
        $map = clone $this;
303 1
        $map->keys = $this
304 1
            ->keys
305 1
            ->slice(0, $index)
306 1
            ->append($this->keys->slice($index + 1, $this->keys->size()));
307 1
        $map->values = $this
308 1
            ->values
309 1
            ->slice(0, $index)
310 1
            ->append($this->values->slice($index + 1, $this->values->size()));
311
        /** @var Sequence<Pair<T, S>> */
312 1
        $map->pairs = $this
0 ignored issues
show
Bug introduced by
The property pairs does not seem to exist on Innmind\Immutable\Sequence.
Loading history...
313 1
            ->pairs
314 1
            ->slice(0, $index)
315 1
            ->append($this->pairs->slice($index + 1, $this->pairs->size()));
316
317 1
        return $map;
318
    }
319
320
    /**
321
     * @param Implementation<T, S> $map
322
     *
323
     * @return self<T, S>
324
     */
325 1
    public function merge(Implementation $map): self
326
    {
327 1
        return $map->reduce(
328 1
            $this,
329
            function(self $carry, $key, $value): self {
330 1
                return $carry->put($key, $value);
331 1
            }
332
        );
333
    }
334
335
    /**
336
     * @param callable(T, S): bool $predicate
337
     *
338
     * @return Map<bool, Map<T, S>>
339
     */
340 1
    public function partition(callable $predicate): Map
341
    {
342 1
        $truthy = $this->clearMap();
343 1
        $falsy = $this->clearMap();
344
345 1
        foreach ($this->pairs->toArray() as $pair) {
346 1
            $return = $predicate($pair->key(), $pair->value());
347
348 1
            if ($return === true) {
349 1
                $truthy = ($truthy)($pair->key(), $pair->value());
350
            } else {
351 1
                $falsy = ($falsy)($pair->key(), $pair->value());
352
            }
353
        }
354
355
        /**
356
         * @psalm-suppress InvalidScalarArgument
357
         * @psalm-suppress InvalidArgument
358
         */
359 1
        return Map::of('bool', Map::class)
360 1
            (true, $truthy)
361 1
            (false, $falsy);
362
    }
363
364
    /**
365
     * @template R
366
     * @param R $carry
0 ignored issues
show
Bug introduced by
The type Innmind\Immutable\Map\R was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
367
     * @param callable(R, T, S): R $reducer
368
     *
369
     * @return R
370
     */
371 2
    public function reduce($carry, callable $reducer)
372
    {
373 2
        foreach ($this->pairs->toArray() as $pair) {
374 2
            $carry = $reducer($carry, $pair->key(), $pair->value());
375
        }
376
377 2
        return $carry;
378
    }
379
380 3
    public function empty(): bool
381
    {
382 3
        return $this->pairs->empty();
383
    }
384
385
    /**
386
     * @template ST
387
     *
388
     * @param callable(T, S): \Generator<ST> $mapper
389
     *
390
     * @return Set<ST>
391
     */
392 1
    public function toSetOf(string $type, callable $mapper): Set
393
    {
394
        /** @var Set<ST> */
395 1
        $set = Set::of($type);
396
397 1
        foreach (unwrap($this->pairs) as $pair) {
0 ignored issues
show
Bug introduced by
$this->pairs of type Innmind\Immutable\Sequence is incompatible with the type Innmind\Immutable\Set expected by parameter $structure of Innmind\Immutable\unwrap(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

397
        foreach (unwrap(/** @scrutinizer ignore-type */ $this->pairs) as $pair) {
Loading history...
398 1
            foreach ($mapper($pair->key(), $pair->value()) as $newValue) {
399 1
                $set = ($set)($newValue);
400
            }
401
        }
402
403 1
        return $set;
404
    }
405
406
    /**
407
     * @return Map<T, S>
408
     */
409 2
    private function clearMap(): Map
410
    {
411 2
        return Map::of($this->keyType, $this->valueType);
412
    }
413
}
414