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