File tree Expand file tree Collapse file tree 3 files changed +42
-2
lines changed
Expand file tree Collapse file tree 3 files changed +42
-2
lines changed Original file line number Diff line number Diff line change @@ -50,7 +50,7 @@ class WindowIterator implements Iterator
5050
5151 /**
5252 * @param Iterator<TKey, TValue> $inner
53- * @param int|null $maxSize Maximum buffer size (null = unlimited)
53+ * @param int<1, max> |null $maxSize Maximum buffer size (null = unlimited)
5454 */
5555 public function __construct (
5656 private readonly Iterator $ inner ,
@@ -123,6 +123,13 @@ private function initialize(): void
123123 }
124124 $ this ->initialized = true ;
125125
126+ // If inner is already pointing at data (e.g. a started generator), capture it
127+ if ($ this ->inner ->valid ()) {
128+ $ this ->pushFromInner ();
129+
130+ return ;
131+ }
132+
126133 $ this ->fetch (rewind: true );
127134 }
128135
@@ -139,6 +146,11 @@ private function fetch(bool $rewind = false): void
139146 return ;
140147 }
141148
149+ $ this ->pushFromInner ();
150+ }
151+
152+ private function pushFromInner (): void
153+ {
142154 $ this ->buffer ->push ([$ this ->inner ->key (), $ this ->inner ->current ()]);
143155 }
144156}
Original file line number Diff line number Diff line change @@ -691,7 +691,7 @@ public function cursor(): Iterator
691691 *
692692 * With a size limit, oldest elements are dropped (sliding window).
693693 *
694- * @param int|null $size Maximum buffer size (null = unlimited)
694+ * @param int<1, max> |null $size Maximum buffer size (null = unlimited)
695695 * @return Iterator<TKey, TValue>
696696 */
697697 public function window (?int $ size = null ): Iterator
Original file line number Diff line number Diff line change @@ -408,4 +408,32 @@ public function valid(): bool
408408 $ window ->next ();
409409 $ this ->assertSame (0 , $ nextCalls );
410410 }
411+
412+ public function testWindowWithStartedGenerator (): void
413+ {
414+ $ generator = (function () {
415+ yield 1 ;
416+ yield 2 ;
417+ yield 3 ;
418+ })();
419+
420+ // Advance the generator - it's now "dirty"
421+ $ generator ->next ();
422+ $ this ->assertSame (2 , $ generator ->current ());
423+
424+ // Wrapping in WindowIterator should not throw "Cannot rewind a generator"
425+ $ window = new WindowIterator ($ generator );
426+
427+ // Should capture current element (2) and continue
428+ $ collected = [];
429+ foreach ($ window as $ value ) {
430+ $ collected [] = $ value ;
431+ }
432+
433+ $ this ->assertSame ([2 , 3 ], $ collected );
434+
435+ // Can rewind and replay
436+ $ window ->rewind ();
437+ $ this ->assertSame ([2 , 3 ], take ($ window )->toList ());
438+ }
411439}
You can’t perform that action at this time.
0 commit comments