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 ( 2e42f3...4471cd )
by Baptiste
01:50
created

src/Sequence.php (1 issue)

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 123
    private function __construct(string $type, Sequence\Implementation $implementation)
23
    {
24 123
        $this->type = $type;
25 123
        $this->validate = Type::of($type);
26 123
        $this->implementation = $implementation;
27 123
    }
28
29
    /**
30
     * @param T $values
31
     *
32
     * @return self<T>
33
     */
34 114
    public static function of(string $type, ...$values): self
35
    {
36 114
        $self = new self($type, new Sequence\Primitive($type, ...$values));
37 114
        $self->implementation->reduce(
38 114
            1,
39
            static function(int $position, $element) use ($self): int {
40 30
                ($self->validate)($element, $position);
41
42 30
                return ++$position;
43 114
            }
44
        );
45
46 114
        return $self;
47
    }
48
49
    /**
50
     * It will load the values inside the generator only upon the first use
51
     * of the sequence
52
     *
53
     * Use this mode when the amount of data may not fit in memory
54
     *
55
     * @param \Generator<T> $generator
56
     *
57
     * @return self<T>
58
     */
59 4
    public static function defer(string $type, \Generator $generator): self
60
    {
61 4
        return new self($type, new Sequence\Defer($type, $generator));
62
    }
63
64
    /**
65
     * It will call the given function every time a new operation is done on the
66
     * sequence. This means the returned structure may not be truly immutable
67
     * as between the calls the underlying source may change.
68
     *
69 1
     * Use this mode when calling to an external source (meaning IO bound) such
70
     * as parsing a file or calling an API
71
     *
72 1
     * @param callable(): \Generator<T> $generator
73
     *
74 1
     * @return self<T>
75
     */
76
    public static function lazy(string $type, callable $generator): self
77
    {
78
        return new self($type, new Sequence\Lazy($type, $generator));
79
    }
80 6
81
    /**
82
     * @param mixed $values
83 6
     *
84
     * @return self<mixed>
85 6
     */
86
    public static function mixed(...$values): self
87
    {
88
        return new self('mixed', new Sequence\Primitive('mixed', ...$values));
89
    }
90
91 1
    /**
92
     * @return self<int>
93
     */
94 1
    public static function ints(int ...$values): self
95
    {
96 1
        /** @var self<int> */
97
        $self = new self('int', new Sequence\Primitive('int', ...$values));
98
99
        return $self;
100
    }
101
102 1
    /**
103
     * @return self<float>
104
     */
105 1
    public static function floats(float ...$values): self
106
    {
107 1
        /** @var self<float> */
108
        $self = new self('float', new Sequence\Primitive('float', ...$values));
109
110
        return $self;
111
    }
112
113 1
    /**
114
     * @return self<string>
115
     */
116 1
    public static function strings(string ...$values): self
117
    {
118 1
        /** @var self<string> */
119
        $self = new self('string', new Sequence\Primitive('string', ...$values));
120
121 26
        return $self;
122
    }
123 26
124
    /**
125
     * @return self<object>
126
     */
127
    public static function objects(object ...$values): self
128
    {
129 39
        /** @var self<object> */
130
        $self = new self('object', new Sequence\Primitive('object', ...$values));
131 39
132
        return $self;
133
    }
134 1
135
    public function isOfType(string $type): bool
136 1
    {
137
        return $this->type === $type;
138
    }
139
140
    /**
141
     * Type of the elements
142 5
     */
143
    public function type(): string
144 5
    {
145
        return $this->type;
146
    }
147
148
    public function size(): int
149
    {
150
        return $this->implementation->size();
151
    }
152
153
    /**
154 9
     * {@inheritdoc}
155
     */
156
    public function count(): int
157 9
    {
158
        return $this->implementation->size();
159
    }
160
161
    /**
162
     * Return the element at the given index
163
     *
164
     * @throws OutOfBoundException
165
     *
166
     * @return T
167 1
     */
168
    public function get(int $index)
169 1
    {
170
        /** @var T */
171 1
        return $this->implementation->get($index);
172 1
    }
173 1
174
    /**
175
     * Return the diff between this sequence and another
176 1
     *
177
     * @param self<T> $sequence
178
     *
179
     * @return self<T>
180
     */
181
    public function diff(self $sequence): self
182
    {
183
        assertSequence($this->type, $sequence, 1);
184 1
185
        $self = clone $this;
186 1
        $self->implementation = $this->implementation->diff(
187 1
            $sequence->implementation,
188
        );
189 1
190
        return $self;
191
    }
192
193
    /**
194
     * Remove all duplicates from the sequence
195
     *
196
     * @return self<T>
197 1
     */
198
    public function distinct(): self
199 1
    {
200 1
        $self = clone $this;
201
        $self->implementation = $this->implementation->distinct();
202 1
203
        return $self;
204
    }
205
206
    /**
207
     * Remove the n first elements
208
     *
209
     * @return self<T>
210 1
     */
211
    public function drop(int $size): self
212 1
    {
213 1
        $self = clone $this;
214
        $self->implementation = $this->implementation->drop($size);
215 1
216
        return $self;
217
    }
218
219
    /**
220
     * Remove the n last elements
221
     *
222
     * @return self<T>
223 7
     */
224
    public function dropEnd(int $size): self
225 7
    {
226
        $self = clone $this;
227 6
        $self->implementation = $this->implementation->dropEnd($size);
228 6
229
        return $self;
230
    }
231
232
    /**
233
     * Check if the two sequences are equal
234
     *
235
     * @param self<T> $sequence
236
     */
237
    public function equals(self $sequence): bool
238
    {
239 1
        assertSequence($this->type, $sequence, 1);
240
241 1
        return $this->implementation->equals(
242 1
            $sequence->implementation,
243
        );
244 1
    }
245
246
    /**
247
     * Return all elements that satisfy the given predicate
248
     *
249
     * @param callable(T): bool $predicate
250
     *
251
     * @return self<T>
252 1
     */
253
    public function filter(callable $predicate): self
254 1
    {
255 1
        $self = clone $this;
256
        $self->implementation = $this->implementation->filter($predicate);
257
258
        return $self;
259
    }
260
261
    /**
262
     * Apply the given function to all elements of the sequence
263
     *
264
     * @param callable(T): void $function
265
     */
266
    public function foreach(callable $function): void
267
    {
268 2
        $this->implementation->foreach($function);
269
    }
270 2
271
    /**
272
     * Return a new map of pairs grouped by keys determined with the given
273
     * discriminator function
274
     *
275
     * @template D
276
     * @param callable(T): D $discriminator
277
     *
278 4
     * @throws CannotGroupEmptyStructure
279
     *
280
     * @return Map<D, self<T>>
281 4
     */
282
    public function groupBy(callable $discriminator): Map
283
    {
284
        return $this->implementation->groupBy($discriminator);
285
    }
286
287
    /**
288
     * Return the first element
289 4
     *
290
     * @return T
291
     */
292 4
    public function first()
293
    {
294
        /** @var T */
295
        return $this->implementation->first();
296
    }
297
298
    /**
299
     * Return the last element
300 1
     *
301
     * @return T
302 1
     */
303
    public function last()
304 1
    {
305
        /** @var T */
306
        return $this->implementation->last();
307
    }
308
309
    /**
310
     * Check if the sequence contains the given element
311
     *
312
     * @param T $element
313
     */
314 1
    public function contains($element): bool
315
    {
316 1
        ($this->validate)($element, 1);
317
318 1
        return $this->implementation->contains($element);
319
    }
320
321
    /**
322
     * Return the index for the given element
323
     *
324
     * @param T $element
325
     *
326 2
     * @throws ElementNotFound
327
     */
328
    public function indexOf($element): int
329 2
    {
330
        ($this->validate)($element, 1);
331 2
332
        return $this->implementation->indexOf($element);
333
    }
334
335
    /**
336
     * Return the list of indices
337
     *
338
     * @return self<int>
339
     */
340
    public function indices(): self
341 3
    {
342
        /** @var self<int> */
343 3
        $self = new self('int', $this->implementation->indices());
344 3
345
        return $self;
346 2
    }
347
348
    /**
349
     * Return a new sequence by applying the given function to all elements
350
     *
351
     * @param callable(T): T $function
352
     *
353
     * @return self<T>
354
     */
355
    public function map(callable $function): self
356 2
    {
357
        $self = clone $this;
358 2
        $self->implementation = $this->implementation->map($function);
359
360 1
        return $self;
361 1
    }
362
363 1
    /**
364
     * Create a new Sequence with the exact same number of elements but with a
365
     * new type transformed via the given function
366
     *
367
     * @template S
368
     *
369
     * @param callable(T): S $map
370
     *
371
     * @return self<S>
372
     */
373 1
    public function mapTo(string $type, callable $map): self
374
    {
375 1
        /** @psalm-suppress MixedArgument */
376
        return $this->toSequenceOf(
377
            $type,
378
            static fn($value): \Generator => yield $map($value),
0 ignored issues
show
A parse error occurred: Syntax error, unexpected T_FN, expecting T_PAAMAYIM_NEKUDOTAYIM on line 378 at column 19
Loading history...
379
        );
380
    }
381
382
    /**
383 1
     * Pad the sequence to a defined size with the given element
384
     *
385 1
     * @param T $element
386 1
     *
387
     * @return self<T>
388 1
     */
389
    public function pad(int $size, $element): self
390
    {
391
        ($this->validate)($element, 2);
392
393
        $self = clone $this;
394
        $self->implementation = $this->implementation->pad($size, $element);
395
396
        return $self;
397
    }
398 1
399
    /**
400 1
     * Return a sequence of 2 sequences partitioned according to the given predicate
401
     *
402
     * @param callable(T): bool $predicate
403
     *
404
     * @return Map<bool, self<T>>
405
     */
406
    public function partition(callable $predicate): Map
407
    {
408 1
        return $this->implementation->partition($predicate);
409
    }
410 1
411 1
    /**
412
     * Slice the sequence
413 1
     *
414
     * @return self<T>
415
     */
416
    public function slice(int $from, int $until): self
417
    {
418
        $self = clone $this;
419
        $self->implementation = $this->implementation->slice($from, $until);
420
421 1
        return $self;
422
    }
423 1
424 1
    /**
425
     * Split the sequence in a sequence of 2 sequences splitted at the given position
426 1
     *
427
     * @throws OutOfBoundException
428
     *
429
     * @return self<self<T>>
430
     */
431
    public function splitAt(int $position): self
432
    {
433
        return $this->implementation->splitAt($position);
434
    }
435
436 2
    /**
437
     * Return a sequence with the n first elements
438 2
     *
439
     * @return self<T>
440 1
     */
441 1
    public function take(int $size): self
442 1
    {
443
        $self = clone $this;
444
        $self->implementation = $this->implementation->take($size);
445 1
446
        return $self;
447
    }
448
449
    /**
450
     * Return a sequence with the n last elements
451
     *
452
     * @return self<T>
453
     */
454
    public function takeEnd(int $size): self
455
    {
456 2
        $self = clone $this;
457
        $self->implementation = $this->implementation->takeEnd($size);
458 2
459
        return $self;
460 1
    }
461 1
462 1
    /**
463
     * Append the given sequence to the current one
464
     *
465 1
     * @param self<T> $sequence
466
     *
467
     * @return self<T>
468
     */
469
    public function append(self $sequence): self
470
    {
471
        assertSequence($this->type, $sequence, 1);
472
473
        $self = clone $this;
474
        $self->implementation = $this->implementation->append(
475 82
            $sequence->implementation,
476
        );
477 82
478
        return $self;
479 81
    }
480 81
481
    /**
482 81
     * Return a sequence with all elements from the current one that exist
483
     * in the given one
484
     *
485
     * @param self<T> $sequence
486
     *
487
     * @return self<T>
488
     */
489
    public function intersect(self $sequence): self
490
    {
491
        assertSequence($this->type, $sequence, 1);
492
493
        $self = clone $this;
494
        $self->implementation = $this->implementation->intersect(
495
            $sequence->implementation,
496
        );
497
498 51
        return $self;
499
    }
500 51
501
    /**
502
     * Add the given element at the end of the sequence
503
     *
504
     * @param T $element
505
     *
506
     * @return self<T>
507
     */
508
    public function add($element): self
509
    {
510 1
        return ($this)($element);
511
    }
512 1
513 1
    /**
514
     * Add the given element at the end of the sequence
515 1
     *
516
     * Example:
517
     * <code>
518
     * Sequence::of('int')(1)(3)
519
     * </code>
520
     *
521
     * @param T $element
522
     *
523
     * @return self<T>
524
     */
525
    public function __invoke($element): self
526
    {
527 87
        ($this->validate)($element, 1);
528
529 87
        $self = clone $this;
530
        $self->implementation = ($this->implementation)($element);
531
532
        return $self;
533
        return $this->add($element);
534
    }
535
536
    /**
537 1
     * Sort the sequence in a different order
538
     *
539 1
     * @param callable(T, T): int $function
540 1
     *
541
     * @return self<T>
542 1
     */
543
    public function sort(callable $function): self
544
    {
545
        $self = clone $this;
546
        $self->implementation = $this->implementation->sort($function);
547
548
        return $self;
549
    }
550 3
551
    /**
552 3
     * Reduce the sequence to a single value
553 3
     *
554
     * @template R
555 3
     * @param R $carry
556
     * @param callable(R, T): R $reducer
557
     *
558 1
     * @return R
559
     */
560 1
    public function reduce($carry, callable $reducer)
561
    {
562
        return $this->implementation->reduce($carry, $reducer);
563
    }
564
565
    /**
566
     * Return a set of the same type but without any value
567
     *
568
     * @return self<T>
569
     */
570 8
    public function clear(): self
571
    {
572 8
        $self = clone $this;
573
        $self->implementation = new Sequence\Primitive($this->type);
574
575
        return $self;
576
    }
577
578
    /**
579
     * Return the same sequence but in reverse order
580
     *
581
     * @return self<T>
582 7
     */
583
    public function reverse(): self
584 7
    {
585
        $self = clone $this;
586
        $self->implementation = $this->implementation->reverse();
587
588
        return $self;
589
    }
590
591
    public function empty(): bool
592
    {
593
        return $this->implementation->empty();
594
    }
595
596
    /**
597 1
     * @template ST
598
     *
599 1
     * @param null|callable(T): \Generator<ST> $mapper
600
     *
601
     * @return self<ST>
602
     */
603
    public function toSequenceOf(string $type, callable $mapper = null): self
604
    {
605
        return $this->implementation->toSequenceOf($type, $mapper);
606
    }
607
608
    /**
609
     * @template ST
610
     *
611
     * @param null|callable(T): \Generator<ST> $mapper
612
     *
613
     * @return Set<ST>
614
     */
615
    public function toSetOf(string $type, callable $mapper = null): Set
616
    {
617
        return $this->implementation->toSetOf($type, $mapper);
618
    }
619
620
    /**
621
     * @template MT
622
     * @template MS
623
     *
624
     * @param callable(T): \Generator<MT, MS> $mapper
625
     *
626
     * @return Map<MT, MS>
627
     */
628
    public function toMapOf(string $key, string $value, callable $mapper): Map
629
    {
630
        return $this->implementation->toMapOf($key, $value, $mapper);
631
    }
632
}
633