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 ( 7ab88f...fff013 )
by Baptiste
07:46
created

src/Sequence.php (3 issues)

Labels
Severity
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Immutable;
5
6
use Innmind\Immutable\Exception\{
7
    LogicException,
8
    CannotGroupEmptyStructure,
9
    ElementNotFound,
10
    OutOfBoundException,
11
};
12
13
/**
14
 * @template T
15
 */
16
final class Sequence implements \Countable
17
{
18
    private string $type;
19
    private ValidateArgument $validate;
20
    private Sequence\Implementation $implementation;
21
22 222
    private function __construct(string $type, Sequence\Implementation $implementation)
23
    {
24 222
        $this->type = $type;
25 222
        $this->validate = Type::of($type);
26 222
        $this->implementation = $implementation;
27 222
    }
28
29
    /**
30
     * @param T $values
31
     *
32
     * @return self<T>
33
     */
34 216
    public static function of(string $type, ...$values): self
35
    {
36 216
        $self = new self($type, new Sequence\Primitive($type, ...$values));
37 216
        $self->implementation->reduce(
38 216
            1,
39
            static function(int $position, $element) use ($self): int {
40 74
                ($self->validate)($element, $position);
41
42 74
                return ++$position;
43 216
            }
44
        );
45
46 216
        return $self;
47
    }
48
49
    /**
50
     * @param mixed $values
51
     *
52
     * @return self<mixed>
53
     */
54 1
    public static function mixed(...$values): self
55
    {
56
        /** @var self<mixed> */
57 1
        $self = new self('mixed', new Sequence\Primitive('mixed', ...$values));
58
59 1
        return $self;
60
    }
61
62
    /**
63
     * @return self<int>
64
     */
65 6
    public static function ints(int ...$values): self
66
    {
67
        /** @var self<int> */
68 6
        $self = new self('int', new Sequence\Primitive('int', ...$values));
0 ignored issues
show
$values of type integer is incompatible with the type Innmind\Immutable\Sequence\T expected by parameter $values of Innmind\Immutable\Sequen...rimitive::__construct(). ( Ignorable by Annotation )

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

68
        $self = new self('int', new Sequence\Primitive('int', /** @scrutinizer ignore-type */ ...$values));
Loading history...
69
70 6
        return $self;
71
    }
72
73
    /**
74
     * @return self<float>
75
     */
76 1
    public static function floats(float ...$values): self
77
    {
78
        /** @var self<float> */
79 1
        $self = new self('float', new Sequence\Primitive('float', ...$values));
0 ignored issues
show
$values of type double is incompatible with the type Innmind\Immutable\Sequence\T expected by parameter $values of Innmind\Immutable\Sequen...rimitive::__construct(). ( Ignorable by Annotation )

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

79
        $self = new self('float', new Sequence\Primitive('float', /** @scrutinizer ignore-type */ ...$values));
Loading history...
80
81 1
        return $self;
82
    }
83
84
    /**
85
     * @return self<string>
86
     */
87 1
    public static function strings(string ...$values): self
88
    {
89
        /** @var self<string> */
90 1
        $self = new self('string', new Sequence\Primitive('string', ...$values));
0 ignored issues
show
$values of type string is incompatible with the type Innmind\Immutable\Sequence\T expected by parameter $values of Innmind\Immutable\Sequen...rimitive::__construct(). ( Ignorable by Annotation )

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

90
        $self = new self('string', new Sequence\Primitive('string', /** @scrutinizer ignore-type */ ...$values));
Loading history...
91
92 1
        return $self;
93
    }
94
95
    /**
96
     * @return self<object>
97
     */
98 1
    public static function objects(object ...$values): self
99
    {
100
        /** @var self<object> */
101 1
        $self = new self('object', new Sequence\Primitive('object', ...$values));
102
103 1
        return $self;
104
    }
105
106 41
    public function isOfType(string $type): bool
107
    {
108 41
        return $this->type === $type;
109
    }
110
111
    /**
112
     * Type of the elements
113
     */
114 39
    public function type(): string
115
    {
116 39
        return $this->type;
117
    }
118
119 19
    public function size(): int
120
    {
121 19
        return $this->implementation->size();
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127 8
    public function count(): int
128
    {
129 8
        return $this->implementation->size();
130
    }
131
132
    /**
133
     * Return the element at the given index
134
     *
135
     * @throws OutOfBoundException
136
     *
137
     * @return T
138
     */
139 24
    public function get(int $index)
140
    {
141
        /** @var T */
142 24
        return $this->implementation->get($index);
143
    }
144
145
    /**
146
     * Return the diff between this sequence and another
147
     *
148
     * @param self<T> $sequence
149
     *
150
     * @return self<T>
151
     */
152 3
    public function diff(self $sequence): self
153
    {
154 3
        assertSequence($this->type, $sequence, 1);
155
156 3
        $self = clone $this;
157 3
        $self->implementation = $this->implementation->diff(
158 3
            $sequence->implementation
159
        );
160
161 3
        return $self;
162
    }
163
164
    /**
165
     * Remove all duplicates from the sequence
166
     *
167
     * @return self<T>
168
     */
169 96
    public function distinct(): self
170
    {
171 96
        $self = clone $this;
172 96
        $self->implementation = $this->implementation->distinct();
173
174 96
        return $self;
175
    }
176
177
    /**
178
     * Remove the n first elements
179
     *
180
     * @return self<T>
181
     */
182 4
    public function drop(int $size): self
183
    {
184 4
        $self = clone $this;
185 4
        $self->implementation = $this->implementation->drop($size);
186
187 4
        return $self;
188
    }
189
190
    /**
191
     * Remove the n last elements
192
     *
193
     * @return self<T>
194
     */
195 1
    public function dropEnd(int $size): self
196
    {
197 1
        $self = clone $this;
198 1
        $self->implementation = $this->implementation->dropEnd($size);
199
200 1
        return $self;
201
    }
202
203
    /**
204
     * Check if the two sequences are equal
205
     *
206
     * @param self<T> $sequence
207
     */
208 7
    public function equals(self $sequence): bool
209
    {
210 7
        assertSequence($this->type, $sequence, 1);
211
212 6
        return $this->implementation->equals(
213 6
            $sequence->implementation
214
        );
215
    }
216
217
    /**
218
     * Return all elements that satisfy the given predicate
219
     *
220
     * @param callable(T): bool $predicate
221
     *
222
     * @return self<T>
223
     */
224 3
    public function filter(callable $predicate): self
225
    {
226 3
        $self = clone $this;
227 3
        $self->implementation = $this->implementation->filter($predicate);
228
229 3
        return $self;
230
    }
231
232
    /**
233
     * Apply the given function to all elements of the sequence
234
     *
235
     * @param callable(T): void $function
236
     */
237 3
    public function foreach(callable $function): void
238
    {
239 3
        $this->implementation->foreach($function);
240 3
    }
241
242
    /**
243
     * Return a new map of pairs grouped by keys determined with the given
244
     * discriminator function
245
     *
246
     * @template D
247
     * @param callable(T): D $discriminator
248
     *
249
     * @throws CannotGroupEmptyStructure
250
     *
251
     * @return Map<D, self<T>>
252
     */
253 4
    public function groupBy(callable $discriminator): Map
254
    {
255 4
        return $this->implementation->groupBy($discriminator);
256
    }
257
258
    /**
259
     * Return the first element
260
     *
261
     * @return T
262
     */
263 3
    public function first()
264
    {
265
        /** @var T */
266 3
        return $this->implementation->first();
267
    }
268
269
    /**
270
     * Return the last element
271
     *
272
     * @return T
273
     */
274 3
    public function last()
275
    {
276
        /** @var T */
277 3
        return $this->implementation->last();
278
    }
279
280
    /**
281
     * Check if the sequence contains the given element
282
     *
283
     * @param T $element
284
     */
285 67
    public function contains($element): bool
286
    {
287 67
        ($this->validate)($element, 1);
288
289 67
        return $this->implementation->contains($element);
290
    }
291
292
    /**
293
     * Return the index for the given element
294
     *
295
     * @param T $element
296
     *
297
     * @throws ElementNotFound
298
     */
299 19
    public function indexOf($element): int
300
    {
301 19
        ($this->validate)($element, 1);
302
303 19
        return $this->implementation->indexOf($element);
304
    }
305
306
    /**
307
     * Return the list of indices
308
     *
309
     * @return self<int>
310
     */
311 2
    public function indices(): self
312
    {
313
        /** @var self<int> */
314 2
        $self = new self('int', $this->implementation->indices());
315
316 2
        return $self;
317
    }
318
319
    /**
320
     * Return a new sequence by applying the given function to all elements
321
     *
322
     * @param callable(T): T $function
323
     *
324
     * @return self<T>
325
     */
326 3
    public function map(callable $function): self
327
    {
328 3
        $self = clone $this;
329 3
        $self->implementation = $this->implementation->map($function);
330
331 2
        return $self;
332
    }
333
334
    /**
335
     * Pad the sequence to a defined size with the given element
336
     *
337
     * @param T $element
338
     *
339
     * @return self<T>
340
     */
341 2
    public function pad(int $size, $element): self
342
    {
343 2
        ($this->validate)($element, 2);
344
345 1
        $self = clone $this;
346 1
        $self->implementation = $this->implementation->pad($size, $element);
347
348 1
        return $self;
349
    }
350
351
    /**
352
     * Return a sequence of 2 sequences partitioned according to the given predicate
353
     *
354
     * @param callable(T): bool $predicate
355
     *
356
     * @return Map<bool, self<T>>
357
     */
358 3
    public function partition(callable $predicate): Map
359
    {
360 3
        return $this->implementation->partition($predicate);
361
    }
362
363
    /**
364
     * Slice the sequence
365
     *
366
     * @return self<T>
367
     */
368 4
    public function slice(int $from, int $until): self
369
    {
370 4
        $self = clone $this;
371 4
        $self->implementation = $this->implementation->slice($from, $until);
372
373 4
        return $self;
374
    }
375
376
    /**
377
     * Split the sequence in a sequence of 2 sequences splitted at the given position
378
     *
379
     * @throws OutOfBoundException
380
     *
381
     * @return self<self<T>>
382
     */
383 1
    public function splitAt(int $position): self
384
    {
385 1
        return $this->implementation->splitAt($position);
386
    }
387
388
    /**
389
     * Return a sequence with the n first elements
390
     *
391
     * @return self<T>
392
     */
393 4
    public function take(int $size): self
394
    {
395 4
        $self = clone $this;
396 4
        $self->implementation = $this->implementation->take($size);
397
398 4
        return $self;
399
    }
400
401
    /**
402
     * Return a sequence with the n last elements
403
     *
404
     * @return self<T>
405
     */
406 1
    public function takeEnd(int $size): self
407
    {
408 1
        $self = clone $this;
409 1
        $self->implementation = $this->implementation->takeEnd($size);
410
411 1
        return $self;
412
    }
413
414
    /**
415
     * Append the given sequence to the current one
416
     *
417
     * @param self<T> $sequence
418
     *
419
     * @return self<T>
420
     */
421 8
    public function append(self $sequence): self
422
    {
423 8
        assertSequence($this->type, $sequence, 1);
424
425 7
        $self = clone $this;
426 7
        $self->implementation = $this->implementation->append(
427 7
            $sequence->implementation
428
        );
429
430 7
        return $self;
431
    }
432
433
    /**
434
     * Return a sequence with all elements from the current one that exist
435
     * in the given one
436
     *
437
     * @param self<T> $sequence
438
     *
439
     * @return self<T>
440
     */
441 14
    public function intersect(self $sequence): self
442
    {
443 14
        assertSequence($this->type, $sequence, 1);
444
445 13
        $self = clone $this;
446 13
        $self->implementation = $this->implementation->intersect(
447 13
            $sequence->implementation
448
        );
449
450 13
        return $self;
451
    }
452
453
    /**
454
     * Add the given element at the end of the sequence
455
     *
456
     * @param T $element
457
     *
458
     * @return self<T>
459
     */
460 119
    public function add($element): self
461
    {
462 119
        ($this->validate)($element, 1);
463
464 118
        $self = clone $this;
465 118
        $self->implementation = $this->implementation->add($element);
466
467 118
        return $self;
468
    }
469
470
    /**
471
     * Alias for add method in order to have a syntax similar to a true tuple
472
     * when constructing the sequence
473
     *
474
     * Example:
475
     * <code>
476
     * Sequence::of('int')(1)(3)
477
     * </code>
478
     *
479
     * @param T $element
480
     *
481
     * @return self<T>
482
     */
483 89
    public function __invoke($element): self
484
    {
485 89
        return $this->add($element);
486
    }
487
488
    /**
489
     * Sort the sequence in a different order
490
     *
491
     * @param callable(T, T): int $function
492
     *
493
     * @return self<T>
494
     */
495 3
    public function sort(callable $function): self
496
    {
497 3
        $self = clone $this;
498 3
        $self->implementation = $this->implementation->sort($function);
499
500 3
        return $self;
501
    }
502
503
    /**
504
     * Reduce the sequence to a single value
505
     *
506
     * @template R
507
     * @param R $carry
508
     * @param callable(R, T): R $reducer
509
     *
510
     * @return R
511
     */
512 130
    public function reduce($carry, callable $reducer)
513
    {
514 130
        return $this->implementation->reduce($carry, $reducer);
515
    }
516
517
    /**
518
     * Return a set of the same type but without any value
519
     *
520
     * @return self<T>
521
     */
522 8
    public function clear(): self
523
    {
524 8
        $self = clone $this;
525 8
        $self->implementation = new Sequence\Primitive($this->type);
526
527 8
        return $self;
528
    }
529
530
    /**
531
     * Return the same sequence but in reverse order
532
     *
533
     * @return self<T>
534
     */
535 3
    public function reverse(): self
536
    {
537 3
        $self = clone $this;
538 3
        $self->implementation = $this->implementation->reverse();
539
540 3
        return $self;
541
    }
542
543 8
    public function empty(): bool
544
    {
545 8
        return $this->implementation->empty();
546
    }
547
548
    /**
549
     * @template ST
550
     *
551
     * @param callable(T): \Generator<ST> $mapper
552
     *
553
     * @return self<ST>
554
     */
555 10
    public function toSequenceOf(string $type, callable $mapper): self
556
    {
557 10
        return $this->implementation->toSequenceOf($type, $mapper);
558
    }
559
560
    /**
561
     * @template ST
562
     *
563
     * @param callable(T): \Generator<ST> $mapper
564
     *
565
     * @return Set<ST>
566
     */
567 3
    public function toSetOf(string $type, callable $mapper): Set
568
    {
569 3
        return $this->implementation->toSetOf($type, $mapper);
570
    }
571
572
573
574
    /**
575
     * @template MT
576
     * @template MS
577
     *
578
     * @param callable(T): \Generator<MT, MS> $mapper
579
     *
580
     * @return Map<MT, MS>
581
     */
582 3
    public function toMapOf(string $key, string $value, callable $mapper): Map
583
    {
584 3
        return $this->implementation->toMapOf($key, $value, $mapper);
585
    }
586
}
587