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 ( 7af216...ebf010 )
by Baptiste
13:17
created

Defer::diff()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

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