@@ -18,9 +18,6 @@ final class DeferredGenerator implements \Iterator
1818{
1919 private bool $ started = false ;
2020 private bool $ finished = false ;
21- private mixed $ key = null ;
22- private mixed $ value = null ;
23- private mixed $ result = null ;
2421 private \Generator $ generator ;
2522
2623 /** @var array<\Closure(\Throwable): mixed> */
@@ -50,7 +47,6 @@ public static function fromGenerator(\Generator $generator): self
5047 $ self = new self ();
5148 $ self ->generator = $ generator ;
5249 $ self ->started = true ;
53- $ self ->fill ();
5450 return $ self ;
5551 }
5652
@@ -67,10 +63,8 @@ public function throw(\Throwable $exception): void
6763 );
6864 try {
6965 $ this ->generator ->throw ($ exception );
70- $ this ->fill ();
7166 } catch (\Throwable $ e ) {
7267 $ this ->handleException ($ e );
73- throw $ e ;
7468 }
7569 }
7670
@@ -81,15 +75,12 @@ public function throw(\Throwable $exception): void
8175 */
8276 public function send (mixed $ value ): mixed
8377 {
84- $ this ->started or throw new \ LogicException ( ' Cannot send value to a generator that was not started. ' );
78+ $ this ->start ( );
8579 $ this ->finished and throw new \LogicException ('Cannot send value to a generator that was already finished. ' );
8680 try {
87- $ result = $ this ->generator ->send ($ value );
88- $ this ->fill ();
89- return $ result ;
81+ return $ this ->generator ->send ($ value );
9082 } catch (\Throwable $ e ) {
9183 $ this ->handleException ($ e );
92- throw $ e ;
9384 }
9485 }
9586
@@ -98,8 +89,11 @@ public function send(mixed $value): mixed
9889 */
9990 public function getReturn (): mixed
10091 {
101- $ this ->finished or throw new \LogicException ('Cannot get return value of a generator that was not finished. ' );
102- return $ this ->result ;
92+ try {
93+ return $ this ->generator ->getReturn ();
94+ } catch (\Throwable $ e ) {
95+ $ this ->handleException ($ e );
96+ }
10397 }
10498
10599 /**
@@ -108,7 +102,11 @@ public function getReturn(): mixed
108102 public function current (): mixed
109103 {
110104 $ this ->start ();
111- return $ this ->value ;
105+ try {
106+ return $ this ->generator ->current ();
107+ } catch (\Throwable $ e ) {
108+ $ this ->handleException ($ e );
109+ }
112110 }
113111
114112 /**
@@ -117,7 +115,11 @@ public function current(): mixed
117115 public function key (): mixed
118116 {
119117 $ this ->start ();
120- return $ this ->key ;
118+ try {
119+ return $ this ->generator ->key ();
120+ } catch (\Throwable $ e ) {
121+ $ this ->handleException ($ e );
122+ }
121123 }
122124
123125 /**
@@ -132,10 +134,8 @@ public function next(): void
132134
133135 try {
134136 $ this ->generator ->next ();
135- $ this ->fill ();
136137 } catch (\Throwable $ e ) {
137138 $ this ->handleException ($ e );
138- throw $ e ;
139139 }
140140 }
141141
@@ -147,12 +147,16 @@ public function next(): void
147147 public function valid (): bool
148148 {
149149 $ this ->start ();
150- return !$ this ->finished ;
150+ try {
151+ return $ this ->generator ->valid ();
152+ } catch (\Throwable $ e ) {
153+ $ this ->handleException ($ e );
154+ }
151155 }
152156
153157 public function rewind (): void
154158 {
155- $ this ->started and throw new \ LogicException ( ' Cannot rewind a generator that was already run. ' );
159+ $ this ->generator -> rewind ( );
156160 }
157161
158162 /**
@@ -178,34 +182,34 @@ private function start(): void
178182
179183 if ($ result instanceof \Generator) {
180184 $ this ->generator = $ result ;
181- $ this ->fill ();
182185 return ;
183186 }
184187
185- $ this ->result = $ result ;
188+ $ this ->generator = (static function (mixed $ result ) {
189+ return $ result ;
190+ yield ;
191+ })($ result );
186192 $ this ->finished = true ;
187193 } catch (\Throwable $ e ) {
188194 $ this ->handleException ($ e );
189- throw $ e ;
190195 } finally {
191196 unset($ this ->handler , $ this ->values );
192197 }
193198 }
194199
195- private function fill ( ): void
200+ private function handleException ( \ Throwable $ e ): never
196201 {
197- $ this ->key = $ this ->generator ->key ();
198- $ this ->value = $ this ->generator ->current ();
199- $ this ->finished = !$ this ->generator ->valid () and $ this ->result = $ this ->generator ->getReturn ();
200- }
201-
202- private function handleException (\Throwable $ e ): void
203- {
204- $ this ->key = null ;
205- $ this ->value = null ;
202+ $ this ->finished and throw $ e ;
206203 $ this ->finished = true ;
207204 foreach ($ this ->catchers as $ catch ) {
208- $ catch ($ e );
205+ try {
206+ $ catch ($ e );
207+ } catch (\Throwable ) {
208+ // Do nothing.
209+ }
209210 }
211+
212+ $ this ->catchers = [];
213+ throw $ e ;
210214 }
211215}
0 commit comments