Completed
Push — master ( 75f269...02e63a )
by Lars
02:19
created

ArrayyRewindableGenerator   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 92%

Importance

Changes 0
Metric Value
dl 0
loc 130
ccs 23
cts 25
cp 0.92
rs 10
c 0
b 0
f 0
wmc 9
lcom 1
cbo 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A current() 0 4 1
A key() 0 4 1
A next() 0 4 1
A rewind() 0 8 2
A valid() 0 4 1
A generateGenerator() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arrayy;
6
7
/**
8
 * @template   XKey of array-key
9
 * @template   X
10
 * @implements \Iterator<XKey,X>
11
 *
12
 * @internal
13
 */
14
class ArrayyRewindableGenerator implements \Iterator
15
{
16
    /**
17
     * @var string
18
     *
19
     * @psalm-var string|class-string<\Arrayy\Arrayy<TKey,T>>
20
     */
21
    protected $class;
22
23
    /**
24
     * @var callable
25
     */
26
    protected $generatorFunction;
27
28
    /**
29
     * @var \Generator
30
     *
31
     * @psalm-var \Generator<XKey,X>
32
     */
33
    protected $generator;
34
35
    /**
36
     * @var callable|null
37
     */
38
    protected $onRewind;
39
40
    /**
41
     * @param callable $generatorConstructionFunction A callable that should return a Generator.
42
     * @param callable $onRewind                      Callable that gets invoked with 0 arguments after the iterator
43
     *                                                was rewinded.
44
     * @param string $class
45
     *
46
     * @throws \InvalidArgumentException
47
     */
48 88
    public function __construct(
49
        callable $generatorConstructionFunction,
50
        callable $onRewind = null,
51
        string $class = ''
52
    ) {
53 88
        $this->class = $class;
54 88
        $this->generatorFunction = $generatorConstructionFunction;
55 88
        $this->onRewind = $onRewind;
56 88
        $this->generateGenerator();
57 88
    }
58
59
    /**
60
     * Return the current element.
61
     *
62
     * @return mixed
63
     *
64
     * @see  http://php.net/manual/en/iterator.current.php
65
     * @see  Iterator::current
66
     *
67
     * @psalm-return X
68
     */
69 66
    public function current()
70
    {
71 66
        return $this->generator->current();
72
    }
73
74
    /**
75
     * Return the key of the current element.
76
     *
77
     * @return mixed scalar on success, or null on failure
78
     *
79
     * @see  http://php.net/manual/en/iterator.key.php
80
     * @see  Iterator::key
81
     *
82
     * @psalm-return XKey
83
     */
84 66
    public function key()
85
    {
86 66
        return $this->generator->key();
87
    }
88
89
    /**
90
     * Move forward to next element.
91
     *
92
     * @return void
93
     *
94
     * @see  http://php.net/manual/en/iterator.next.php
95
     * @see  Iterator::next
96
     */
97 55
    public function next()
98
    {
99 55
        $this->generator->next();
100 55
    }
101
102
    /**
103
     * Rewind the Iterator to the first element.
104
     *
105
     * @return void
106
     *
107
     * @see  http://php.net/manual/en/iterator.rewind.php
108
     * @see  Iterator::rewind
109
     */
110 87
    public function rewind()
111
    {
112 87
        $this->generateGenerator();
113
114 87
        if (\is_callable($this->onRewind)) {
115
            \call_user_func($this->onRewind);
116
        }
117 87
    }
118
119
    /**
120
     * Checks if current position is valid.
121
     *
122
     * @return bool
123
     *
124
     * @see  http://php.net/manual/en/iterator.valid.php
125
     * @see  Iterator::rewind
126
     */
127 87
    public function valid(): bool
128
    {
129 87
        return $this->generator->valid();
130
    }
131
132
    /**
133
     * @return void
134
     */
135 88
    private function generateGenerator()
136
    {
137 88
        $this->generator = \call_user_func($this->generatorFunction);
138
139 88
        if (!($this->generator instanceof \Generator)) {
140
            throw new \InvalidArgumentException('The callable needs to return a Generator');
141
        }
142 88
    }
143
}
144