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

ObjectKeys::toSetOf()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 7
c 0
b 0
f 0
nc 3
nop 2
dl 0
loc 17
ccs 8
cts 8
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
    ValidateArgument\ClassType,
15
    Exception\LogicException,
16
    Exception\ElementNotFound,
17
    Exception\CannotGroupEmptyStructure,
18
};
19
20
/**
21
 * @template T
22
 * @template S
23
 */
24
final class ObjectKeys implements Implementation
25
{
26
    private string $keyType;
27
    private string $valueType;
28
    private ValidateArgument $validateKey;
29
    private ValidateArgument $validateValue;
30
    private \SplObjectStorage $values;
31
32 28
    public function __construct(string $keyType, string $valueType)
33
    {
34 28
        $this->validateKey = Type::of($keyType);
35
36 28
        if (!$this->validateKey instanceof ClassType && $keyType !== 'object') {
37 1
            throw new LogicException;
38
        }
39
40 27
        $this->validateValue = Type::of($valueType);
41 27
        $this->keyType = $keyType;
42 27
        $this->valueType = $valueType;
43 27
        $this->values = new \SplObjectStorage;
44 27
    }
45
46 9
    public function keyType(): string
47
    {
48 9
        return $this->keyType;
49
    }
50
51 8
    public function valueType(): string
52
    {
53 8
        return $this->valueType;
54
    }
55
56 7
    public function size(): int
57
    {
58 7
        return $this->values->count();
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function count(): int
65
    {
66
        return $this->size();
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
72
     *
73
     * @return self<T, S>
74
     */
75 23
    public function put($key, $value): Implementation
76
    {
77 23
        ($this->validateKey)($key, 1);
78 22
        ($this->validateValue)($value, 2);
79
80 21
        $map = clone $this;
81 21
        $map->values = clone $this->values;
82
        /** @psalm-suppress MixedArgumentTypeCoercion */
83 21
        $map->values[$key] = $value;
84
85 21
        return $map;
86
    }
87
88
    /**
89
     * @param T $key
90
     *
91
     * @throws ElementNotFound
92
     *
93
     * @return S
94
     */
95 7
    public function get($key)
96
    {
97 7
        if (!$this->contains($key)) {
98 1
            throw new ElementNotFound($key);
99
        }
100
101
        /**
102
         * @psalm-suppress MixedArgumentTypeCoercion
103
         * @var S
104
         */
105 6
        return $this->values->offsetGet($key);
106
    }
107
108
    /**
109
     * @param T $key
110
     */
111 10
    public function contains($key): bool
112
    {
113 10
        if (!is_object($key)) {
114 1
            return false;
115
        }
116
117
        /** @psalm-suppress MixedArgumentTypeCoercion */
118 10
        return $this->values->offsetExists($key);
119
    }
120
121
    /**
122
     * @return self<T, S>
123
     */
124 5
    public function clear(): self
125
    {
126 5
        $map = clone $this;
127 5
        $map->values = new \SplObjectStorage;
128
129 5
        return $map;
130
    }
131
132
    /**
133
     * @param Implementation<T, S> $map
134
     */
135 3
    public function equals(Implementation $map): bool
136
    {
137 3
        if ($map->size() !== $this->size()) {
138 1
            return false;
139
        }
140
141 3
        foreach ($this->values as $k) {
142
            /** @var T $key */
143 3
            $key = $k;
144
            /** @var S $v */
145 3
            $v = $this->values[$k];
146
147 3
            if (!$map->contains($key)) {
148
                return false;
149
            }
150
151 3
            if ($map->get($key) !== $v) {
152 3
                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->values as $k) {
169
            /** @var T $key */
170 1
            $key = $k;
171
            /** @var S $v */
172 1
            $v = $this->values[$k];
173
174 1
            if ($predicate($key, $v) === true) {
175 1
                $map->values[$k] = $v;
176
            }
177
        }
178
179 1
        return $map;
180
    }
181
182
    /**
183
     * @param callable(T, S): void $function
184
     */
185 1
    public function foreach(callable $function): void
186
    {
187 1
        foreach ($this->values as $k) {
188
            /** @var T $key */
189 1
            $key = $k;
190
            /** @var S $v */
191 1
            $v = $this->values[$k];
192
193 1
            $function($key, $v);
194
        }
195 1
    }
196
197
    /**
198
     * @template D
199
     * @param callable(T, S): D $discriminator
200
     *
201
     * @throws CannotGroupEmptyStructure
202
     *
203
     * @return Map<D, Map<T, S>>
204
     */
205 2
    public function groupBy(callable $discriminator): Map
206
    {
207 2
        if ($this->empty()) {
208 1
            throw new CannotGroupEmptyStructure;
209
        }
210
211 1
        $groups = null;
212
213 1
        foreach ($this->values as $k) {
214
            /** @var T $key */
215 1
            $key = $k;
216
            /** @var S $v */
217 1
            $v = $this->values[$k];
218
219 1
            $discriminant = $discriminator($key, $v);
220
221 1
            if ($groups === null) {
222
                /** @var Map<D, Map<T, S>> */
223 1
                $groups = Map::of(
224 1
                    Type::determine($discriminant),
225 1
                    Map::class,
226
                );
227
            }
228
229 1
            if ($groups->contains($discriminant)) {
230
                /** @var Map<T, S> */
231 1
                $group = $groups->get($discriminant);
232
                /** @var Map<T, S> */
233 1
                $group = ($group)($key, $v);
234
235 1
                $groups = ($groups)($discriminant, $group);
236
            } else {
237
                /** @var Map<T, S> */
238 1
                $group = $this->clearMap()($key, $v);
239
240 1
                $groups = ($groups)($discriminant, $group);
241
            }
242
        }
243
244
        /** @var Map<D, Map<T, S>> */
245 1
        return $groups;
246
    }
247
248
    /**
249
     * @return Set<T>
250
     */
251 7
    public function keys(): Set
252
    {
253 7
        return $this->reduce(
254 7
            Set::of($this->keyType),
255
            static function(Set $keys, $key): Set {
256 7
                return ($keys)($key);
257 7
            }
258
        );
259
    }
260
261
    /**
262
     * @return Sequence<S>
263
     */
264 8
    public function values(): Sequence
265
    {
266 8
        return $this->reduce(
267 8
            Sequence::of($this->valueType),
268
            static function(Sequence $values, $key, $value): Sequence {
269 8
                return ($values)($value);
270 8
            }
271
        );
272
    }
273
274
    /**
275
     * @param callable(T, S): (S|Pair<T, S>) $function
276
     *
277
     * @return self<T, S>
278
     */
279 3
    public function map(callable $function): self
280
    {
281 3
        $map = $this->clear();
282
283 3
        foreach ($this->values as $k) {
284
            /** @var T */
285 3
            $key = $k;
286
            /** @var S */
287 3
            $v = $this->values[$k];
288
289 3
            $return = $function($key, $v);
290
291 3
            if ($return instanceof Pair) {
292 2
                ($this->validateKey)($return->key(), 1);
293
294
                /** @var object */
295 1
                $key = $return->key();
296
                /** @var S */
297 1
                $value = $return->value();
298
            } else {
299 2
                $key = $k;
300 2
                $value = $return;
301
            }
302
303 2
            ($this->validateValue)($value, 2);
304
305 1
            $map->values[$key] = $value;
306
        }
307
308 1
        return $map;
309
    }
310
311 1
    public function join(string $separator): Str
312
    {
313 1
        return $this->values()->join($separator);
314
    }
315
316
    /**
317
     * @param T $key
318
     *
319
     * @return self<T, S>
320
     */
321 1
    public function remove($key): self
322
    {
323 1
        if (!$this->contains($key)) {
324 1
            return $this;
325
        }
326
327 1
        $map = clone $this;
328 1
        $map->values = clone $this->values;
329
        /** @psalm-suppress MixedArgumentTypeCoercion */
330 1
        $map->values->detach($key);
331 1
        $map->values->rewind();
332
333 1
        return $map;
334
    }
335
336
    /**
337
     * @param Implementation<T, S> $map
338
     *
339
     * @return self<T, S>
340
     */
341 2
    public function merge(Implementation $map): self
342
    {
343
        /** @var self<T, S> */
344 2
        return $map->reduce(
345 2
            $this,
346
            function(self $carry, $key, $value): self {
347 2
                return $carry->put($key, $value);
348 2
            }
349
        );
350
    }
351
352
    /**
353
     * @param callable(T, S): bool $predicate
354
     *
355
     * @return Map<bool, Map<T, S>>
356
     */
357 1
    public function partition(callable $predicate): Map
358
    {
359 1
        $truthy = $this->clearMap();
360 1
        $falsy = $this->clearMap();
361
362 1
        foreach ($this->values as $k) {
363
            /** @var T $key */
364 1
            $key = $k;
365
            /** @var S $v */
366 1
            $v = $this->values[$k];
367
368 1
            $return = $predicate($key, $v);
369
370 1
            if ($return === true) {
371 1
                $truthy = ($truthy)($key, $v);
372
            } else {
373 1
                $falsy = ($falsy)($key, $v);
374
            }
375
        }
376
377
        /**
378
         * @psalm-suppress InvalidScalarArgument
379
         * @psalm-suppress InvalidArgument
380
         */
381 1
        return Map::of('bool', Map::class)
382 1
            (true, $truthy)
383 1
            (false, $falsy);
384
    }
385
386
    /**
387
     * @template R
388
     * @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...
389
     * @param callable(R, T, S): R $reducer
390
     *
391
     * @return R
392
     */
393 9
    public function reduce($carry, callable $reducer)
394
    {
395 9
        foreach ($this->values as $k) {
396
            /** @var T $key */
397 9
            $key = $k;
398
            /** @var S $v */
399 9
            $v = $this->values[$k];
400
401 9
            $carry = $reducer($carry, $key, $v);
402
        }
403
404 9
        return $carry;
405
    }
406
407 3
    public function empty(): bool
408
    {
409 3
        $this->values->rewind();
410
411 3
        return !$this->values->valid();
412
    }
413
414
    /**
415
     * @template ST
416
     *
417
     * @param callable(T, S): \Generator<ST> $mapper
418
     *
419
     * @return Set<ST>
420
     */
421 1
    public function toSetOf(string $type, callable $mapper): Set
422
    {
423
        /** @var Set<ST> */
424 1
        $set = Set::of($type);
425
426 1
        foreach ($this->values as $k) {
427
            /** @var T $key */
428 1
            $key = $k;
429
            /** @var S $v */
430 1
            $v = $this->values[$k];
431
432 1
            foreach ($mapper($key, $v) as $newValue) {
433 1
                $set = ($set)($newValue);
434
            }
435
        }
436
437 1
        return $set;
438
    }
439
440
    /**
441
     * @return Map<T, S>
442
     */
443 2
    private function clearMap(): Map
444
    {
445 2
        return Map::of($this->keyType, $this->valueType);
446
    }
447
}
448