From bc8af657efa53f3d3a3b76d387a93cd068f60edd Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Sun, 19 Dec 2021 23:07:43 +0100 Subject: [PATCH] Use `loophp/iterators` (#228) * refactor: Depends on `loophp/iterators`. * refactor: Remove `ProxyIterator`. * Remove `ArrayCacheIterator`. * refactor: Use `PackIterableAggregate` in `Pack` operation. * Add `ReturnTypeWillChange` back on iterators. * Add return types. --- composer.json | 3 +- spec/loophp/collection/CollectionSpec.php | 2 +- .../Iterator/ArrayCacheIteratorSpec.php | 55 ----------- .../Iterator/ClosureIteratorSpec.php | 95 ------------------- .../Iterator/IterableIteratorSpec.php | 87 ----------------- .../Iterator/MultipleIterableIteratorSpec.php | 9 +- .../Iterator/PsrCacheIteratorSpec.php | 10 -- .../Iterator/RandomIteratorSpec.php | 5 - .../Iterator/ResourceIteratorSpec.php | 6 +- .../Iterator/StringIteratorSpec.php | 4 +- src/Collection.php | 8 +- src/Iterator/ArrayCacheIterator.php | 94 ------------------ src/Iterator/ClosureIterator.php | 57 ----------- src/Iterator/IterableIterator.php | 34 ------- src/Iterator/MultipleIterableIterator.php | 47 ++++++++- src/Iterator/ProxyIterator.php | 71 -------------- src/Iterator/PsrCacheIterator.php | 19 ++-- src/Iterator/RandomIterator.php | 38 +++++--- src/Iterator/ResourceIterator.php | 45 ++++++++- src/Iterator/StringIterator.php | 44 ++++++++- src/Iterator/TypedIterator.php | 44 ++++++++- src/Operation/Flatten.php | 2 +- src/Operation/Pack.php | 22 ++--- src/Operation/Product.php | 2 +- src/Operation/Transpose.php | 2 +- src/Operation/Unpack.php | 2 +- src/Operation/Zip.php | 2 +- 27 files changed, 227 insertions(+), 582 deletions(-) delete mode 100644 spec/loophp/collection/Iterator/ArrayCacheIteratorSpec.php delete mode 100644 spec/loophp/collection/Iterator/ClosureIteratorSpec.php delete mode 100644 spec/loophp/collection/Iterator/IterableIteratorSpec.php delete mode 100644 src/Iterator/ArrayCacheIterator.php delete mode 100644 src/Iterator/ClosureIterator.php delete mode 100644 src/Iterator/IterableIterator.php delete mode 100644 src/Iterator/ProxyIterator.php diff --git a/composer.json b/composer.json index 53804ba24..fbb4ba7ea 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,8 @@ } ], "require": { - "php": ">= 7.4" + "php": ">= 7.4", + "loophp/iterators": "^1.3" }, "require-dev": { "amphp/parallel-functions": "^1", diff --git a/spec/loophp/collection/CollectionSpec.php b/spec/loophp/collection/CollectionSpec.php index 3fb5f5ac1..792450ed3 100644 --- a/spec/loophp/collection/CollectionSpec.php +++ b/spec/loophp/collection/CollectionSpec.php @@ -22,8 +22,8 @@ use loophp\collection\Collection; use loophp\collection\Contract\Collection as CollectionInterface; use loophp\collection\Contract\Operation; -use loophp\collection\Iterator\ClosureIterator; use loophp\collection\Operation\AbstractOperation; +use loophp\iterators\ClosureIterator; use OutOfBoundsException; use PhpSpec\Exception\Example\FailureException; use PhpSpec\Exception\Example\MatcherException; diff --git a/spec/loophp/collection/Iterator/ArrayCacheIteratorSpec.php b/spec/loophp/collection/Iterator/ArrayCacheIteratorSpec.php deleted file mode 100644 index d175261b5..000000000 --- a/spec/loophp/collection/Iterator/ArrayCacheIteratorSpec.php +++ /dev/null @@ -1,55 +0,0 @@ -beConstructedWith($generator()); - - $this - ->valid() - ->shouldReturn(true); - - if (5 !== iterator_count($this->getWrappedObject())) { - throw new MatcherException('The count is invalid.'); - } - - $this - ->shouldIterateAs( - range('a', 'e') - ); - } - - public function it_is_initializable(): void - { - $this->beConstructedWith(new ArrayIterator([])); - - $this->shouldHaveType(ArrayCacheIterator::class); - } -} diff --git a/spec/loophp/collection/Iterator/ClosureIteratorSpec.php b/spec/loophp/collection/Iterator/ClosureIteratorSpec.php deleted file mode 100644 index 088cfeaa9..000000000 --- a/spec/loophp/collection/Iterator/ClosureIteratorSpec.php +++ /dev/null @@ -1,95 +0,0 @@ - 1, 'bar' => 2]; - - public function it_can_return_a_string_key(): void - { - $this->beConstructedWith(static fn (array $iterable): Generator => yield from $iterable, [self::MAP_DATA]); - - $this->key()->shouldBe('foo'); - $this->next(); - $this->key()->shouldBe('bar'); - } - - public function it_can_return_an_int_key(): void - { - $this->beConstructedWith(static fn (array $iterable): Generator => yield from $iterable, [self::LIST_DATA]); - - $this->key()->shouldBe(0); - $this->next(); - $this->key()->shouldBe(1); - } - - public function it_can_return_inner_iterator(): void - { - $this->beConstructedWith(static fn (array $iterable): Generator => yield from $iterable, [self::LIST_DATA]); - - $this->getInnerIterator()->shouldIterateAs(self::LIST_DATA); - } - - public function it_can_rewind(): void - { - $this->beConstructedWith(static fn (array $iterable): Generator => yield from $iterable, [['foo']]); - - $this->current()->shouldBe('foo'); - - $this->next(); - $this->valid()->shouldBe(false); - $this->current()->shouldBeNull(); - - $this->rewind(); - $this->valid()->shouldBe(true); - $this->current()->shouldBe('foo'); - } - - public function it_is_initializable_from_callable_with_array(): void - { - $this->beConstructedWith(static fn (array $iterable): array => $iterable, [self::LIST_DATA]); - - $this->shouldHaveType(ClosureIterator::class); - - $this->valid()->shouldBe(true); - $this->shouldIterateAs(self::LIST_DATA); - } - - public function it_is_initializable_from_callable_with_generator(): void - { - $data = ['foo' => 1, 2]; - - $this->beConstructedWith(static fn (array $iterable): Generator => yield from $iterable, [$data]); - - $this->shouldHaveType(ClosureIterator::class); - - $this->valid()->shouldBe(true); - $this->shouldIterateAs($data); - } - - public function it_is_initializable_from_callable_with_iterator(): void - { - $this->beConstructedWith(static fn (array $iterable): Iterator => new ArrayIterator($iterable), [self::MAP_DATA]); - - $this->shouldHaveType(ClosureIterator::class); - - $this->valid()->shouldBe(true); - $this->shouldIterateAs(self::MAP_DATA); - } -} diff --git a/spec/loophp/collection/Iterator/IterableIteratorSpec.php b/spec/loophp/collection/Iterator/IterableIteratorSpec.php deleted file mode 100644 index 687f54543..000000000 --- a/spec/loophp/collection/Iterator/IterableIteratorSpec.php +++ /dev/null @@ -1,87 +0,0 @@ -beConstructedWith(['foo' => 1, 'bar' => 2]); - - $this->key()->shouldReturn('foo'); - $this->next(); - $this->key()->shouldReturn('bar'); - } - - public function it_can_get_an_int_key(): void - { - $this->beConstructedWith(range(1, 5)); - - $this->key()->shouldReturn(0); - $this->next(); - $this->key()->shouldReturn(1); - } - - public function it_can_rewind(): void - { - $this->beConstructedWith(['foo']); - - $this->current()->shouldReturn('foo'); - - $this->next(); - $this->current()->shouldReturn(null); - - $this->rewind(); - $this->current()->shouldReturn('foo'); - } - - public function it_can_use_next(): void - { - $this->beConstructedWith(range(1, 5)); - - $this->next()->shouldBeNull(); - - $this->current()->shouldReturn(2); - } - - public function it_is_initializable_from_array(): void - { - $this->beConstructedWith(['foo', 'bar', 'baz']); - - $this->shouldHaveType(IterableIterator::class); - - $this->current()->shouldBeEqualTo('foo'); - } - - public function it_is_initializable_from_generator(): void - { - $gen = static fn (): Generator => yield from ['foo', 'bar', 'baz']; - - $this->beConstructedWith($gen()); - - $this->shouldHaveType(IterableIterator::class); - - $this->current()->shouldBeEqualTo('foo'); - } - - public function it_is_initializable_from_iterator(): void - { - $this->beConstructedWith(new ArrayIterator(['foo', 'bar', 'baz'])); - - $this->shouldHaveType(IterableIterator::class); - - $this->current()->shouldBeEqualTo('foo'); - } -} diff --git a/spec/loophp/collection/Iterator/MultipleIterableIteratorSpec.php b/spec/loophp/collection/Iterator/MultipleIterableIteratorSpec.php index 6e11b1dc8..d7b981fc9 100644 --- a/spec/loophp/collection/Iterator/MultipleIterableIteratorSpec.php +++ b/spec/loophp/collection/Iterator/MultipleIterableIteratorSpec.php @@ -16,13 +16,6 @@ class MultipleIterableIteratorSpec extends ObjectBehavior { - public function it_can_iterate_with_a_single_iterable(): void - { - $this->beConstructedWith([1, 2, 3]); - - $this->getInnerIterator()->shouldIterateAs([1, 2, 3]); - } - public function it_can_iterate_with_multiple_iterables(): void { $this->beConstructedWith([1, 2, 3], new ArrayIterator([4, 5, 6])); @@ -41,7 +34,7 @@ public function it_can_iterate_with_multiple_iterables(): void yield 2 => 6; }; - $this->getInnerIterator()->shouldIterateAs($expected()); + $this->shouldIterateAs($expected()); } public function it_is_initializable_with_a_single_iterable(): void diff --git a/spec/loophp/collection/Iterator/PsrCacheIteratorSpec.php b/spec/loophp/collection/Iterator/PsrCacheIteratorSpec.php index 88ed786d9..9bd99defe 100644 --- a/spec/loophp/collection/Iterator/PsrCacheIteratorSpec.php +++ b/spec/loophp/collection/Iterator/PsrCacheIteratorSpec.php @@ -80,16 +80,6 @@ public function it_can_cache_data(CacheItemPoolInterface $cache): void ->shouldHaveBeenCalledOnce(); } - public function it_can_get_the_inner_iterator(Iterator $iterator, CacheItemPoolInterface $cache): void - { - $this - ->beConstructedWith($iterator, $cache); - - $this - ->getInnerIterator() - ->shouldReturn($iterator); - } - public function it_is_initializable(Iterator $iterator, CacheItemPoolInterface $cache): void { $this->beConstructedWith($iterator, $cache); diff --git a/spec/loophp/collection/Iterator/RandomIteratorSpec.php b/spec/loophp/collection/Iterator/RandomIteratorSpec.php index d3eb80b86..c72c49bc3 100644 --- a/spec/loophp/collection/Iterator/RandomIteratorSpec.php +++ b/spec/loophp/collection/Iterator/RandomIteratorSpec.php @@ -104,11 +104,6 @@ public function it_can_get_key(): void $this->key()->shouldReturn('a'); } - public function it_can_get_the_innerIterator(): void - { - $this->getInnerIterator()->shouldBeAnInstanceOf(ArrayIterator::class); - } - public function it_can_next(): void { $this->beConstructedWith(new ArrayIterator([1, 2, 3])); diff --git a/spec/loophp/collection/Iterator/ResourceIteratorSpec.php b/spec/loophp/collection/Iterator/ResourceIteratorSpec.php index d98b2ac65..3f4403d22 100644 --- a/spec/loophp/collection/Iterator/ResourceIteratorSpec.php +++ b/spec/loophp/collection/Iterator/ResourceIteratorSpec.php @@ -21,7 +21,7 @@ public function it_can_iterate(): void { $this->beConstructedWith(fopen('data://text/plain,ABCD', 'rb')); - $this->getInnerIterator()->shouldIterateAs(['A', 'B', 'C', 'D']); + $this->shouldIterateAs(['A', 'B', 'C', 'D']); } public function it_closes_opened_file_if_needed(): void @@ -30,7 +30,7 @@ public function it_closes_opened_file_if_needed(): void $this->beConstructedWith($file, true); - $this->getInnerIterator()->shouldIterateAs(['a', 'b', 'c']); + $this->shouldIterateAs(['a', 'b', 'c']); if (is_resource($file)) { throw new FailureException('Failed to close resource!'); @@ -57,7 +57,7 @@ public function it_does_not_close_resource_by_default(): void $this->beConstructedWith($file); - $this->getInnerIterator()->shouldIterateAs(['a', 'b', 'c']); + $this->shouldIterateAs(['a', 'b', 'c']); if (!is_resource($file)) { throw new FailureException('Resource was closed but should not have been!'); diff --git a/spec/loophp/collection/Iterator/StringIteratorSpec.php b/spec/loophp/collection/Iterator/StringIteratorSpec.php index 4065c967c..16e8b3a11 100644 --- a/spec/loophp/collection/Iterator/StringIteratorSpec.php +++ b/spec/loophp/collection/Iterator/StringIteratorSpec.php @@ -18,14 +18,14 @@ public function it_can_iterate_with_default_delimiter(): void { $this->beConstructedWith('A string.'); - $this->getInnerIterator()->shouldIterateAs(['A', ' ', 's', 't', 'r', 'i', 'n', 'g', '.']); + $this->shouldIterateAs(['A', ' ', 's', 't', 'r', 'i', 'n', 'g', '.']); } public function it_can_iterate_with_given_delimiter(): void { $this->beConstructedWith('I am a string.', ' '); - $this->getInnerIterator()->shouldIterateAs(['I', 'am', 'a', 'string.']); + $this->shouldIterateAs(['I', 'am', 'a', 'string.']); } public function it_is_initializable_with_default_delimiter(): void diff --git a/src/Collection.php b/src/Collection.php index 6444f3cef..7f31c2ab1 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -15,9 +15,6 @@ use Iterator; use loophp\collection\Contract\Collection as CollectionInterface; use loophp\collection\Contract\Operation; -use loophp\collection\Iterator\ArrayCacheIterator; -use loophp\collection\Iterator\ClosureIterator; -use loophp\collection\Iterator\IterableIterator; use loophp\collection\Iterator\ResourceIterator; use loophp\collection\Iterator\StringIterator; use loophp\collection\Operation\All; @@ -135,6 +132,9 @@ use loophp\collection\Operation\Words; use loophp\collection\Operation\Wrap; use loophp\collection\Operation\Zip; +use loophp\iterators\CachingIteratorAggregate; +use loophp\iterators\ClosureIterator; +use loophp\iterators\IterableIterator; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Cache\Adapter\ArrayAdapter; @@ -484,7 +484,7 @@ public static function fromFile(string $filepath): self public static function fromGenerator(Generator $generator): self { return self::fromIterable( - new ArrayCacheIterator( + new CachingIteratorAggregate( new ClosureIterator( static function (Generator $generator): Generator { while ($generator->valid()) { diff --git a/src/Iterator/ArrayCacheIterator.php b/src/Iterator/ArrayCacheIterator.php deleted file mode 100644 index 3f45f0d25..000000000 --- a/src/Iterator/ArrayCacheIterator.php +++ /dev/null @@ -1,94 +0,0 @@ - - */ -final class ArrayCacheIterator extends ProxyIterator -{ - /** - * @var array - */ - private array $cache = []; - - private int $key = 0; - - /** - * @param Iterator $iterator - */ - public function __construct(Iterator $iterator) - { - $this->iterator = $iterator; - } - - /** - * @return T - */ - #[ReturnTypeWillChange] - public function current() - { - $data = $this->getTupleFromCache($this->key); - - return $data[1]; - } - - /** - * @return TKey - */ - #[ReturnTypeWillChange] - public function key() - { - $data = $this->getTupleFromCache($this->key); - - return $data[0]; - } - - public function next(): void - { - // This is mostly for iterator_count(). - $this->getTupleFromCache($this->key++); - - parent::next(); - } - - public function rewind(): void - { - // No call to parent::rewind() because we do not know if the inner - // iterator can be rewinded or not. - $this->key = 0; - } - - public function valid(): bool - { - return parent::valid() || array_key_exists($this->key, $this->cache); - } - - /** - * @return array{0: TKey, 1: T} - */ - private function getTupleFromCache(int $key): array - { - return $this->cache[$key] ??= [ - parent::key(), - parent::current(), - ]; - } -} diff --git a/src/Iterator/ClosureIterator.php b/src/Iterator/ClosureIterator.php deleted file mode 100644 index 79d86662f..000000000 --- a/src/Iterator/ClosureIterator.php +++ /dev/null @@ -1,57 +0,0 @@ - - */ -final class ClosureIterator extends ProxyIterator -{ - /** - * @var callable(mixed ...$parameters): iterable - */ - private $callable; - - /** - * @var iterable - */ - private iterable $parameters; - - /** - * @param callable(mixed ...$parameters): iterable $callable - * @param iterable $parameters - */ - public function __construct(callable $callable, iterable $parameters) - { - $this->callable = $callable; - $this->parameters = $parameters; - $this->iterator = $this->getGenerator(); - } - - public function rewind(): void - { - $this->iterator = $this->getGenerator(); - } - - /** - * @return Generator - */ - private function getGenerator(): Generator - { - yield from ($this->callable)(...$this->parameters); - } -} diff --git a/src/Iterator/IterableIterator.php b/src/Iterator/IterableIterator.php deleted file mode 100644 index a431e5c79..000000000 --- a/src/Iterator/IterableIterator.php +++ /dev/null @@ -1,34 +0,0 @@ - - */ -final class IterableIterator extends ProxyIterator -{ - /** - * @param iterable $iterable - */ - public function __construct(iterable $iterable) - { - $this->iterator = new ClosureIterator( - static fn (iterable $iterable): Generator => yield from $iterable, - [$iterable] - ); - } -} diff --git a/src/Iterator/MultipleIterableIterator.php b/src/Iterator/MultipleIterableIterator.php index f8ceb8fca..5f29aa195 100644 --- a/src/Iterator/MultipleIterableIterator.php +++ b/src/Iterator/MultipleIterableIterator.php @@ -10,7 +10,10 @@ namespace loophp\collection\Iterator; use AppendIterator; +use Iterator; +use loophp\iterators\IterableIterator; use NoRewindIterator; +use ReturnTypeWillChange; /** * @internal @@ -18,12 +21,17 @@ * @template TKey * @template T * - * @extends ProxyIterator + * @implements Iterator */ -final class MultipleIterableIterator extends ProxyIterator +final class MultipleIterableIterator implements Iterator { /** - * @param iterable $iterables + * @var Iterator + */ + private Iterator $iterator; + + /** + * @param iterable ...$iterables */ public function __construct(iterable ...$iterables) { @@ -35,4 +43,37 @@ public function __construct(iterable ...$iterables) $this->iterator = $appendIterator; } + + /** + * @return T + */ + #[ReturnTypeWillChange] + public function current() + { + return $this->iterator->current(); + } + + /** + * @return TKey + */ + #[ReturnTypeWillChange] + public function key() + { + return $this->iterator->key(); + } + + public function next(): void + { + $this->iterator->next(); + } + + public function rewind(): void + { + $this->iterator->rewind(); + } + + public function valid(): bool + { + return $this->iterator->valid(); + } } diff --git a/src/Iterator/ProxyIterator.php b/src/Iterator/ProxyIterator.php deleted file mode 100644 index 6ff944db0..000000000 --- a/src/Iterator/ProxyIterator.php +++ /dev/null @@ -1,71 +0,0 @@ - - */ -abstract class ProxyIterator implements OuterIterator -{ - /** - * @var Iterator - */ - protected Iterator $iterator; - - /** - * @return T - */ - #[ReturnTypeWillChange] - public function current() - { - return $this->iterator->current(); - } - - /** - * @return Iterator - */ - public function getInnerIterator(): Iterator - { - return $this->iterator; - } - - /** - * @return TKey - */ - #[ReturnTypeWillChange] - public function key() - { - return $this->iterator->key(); - } - - public function next(): void - { - $this->iterator->next(); - } - - public function rewind(): void - { - $this->iterator->rewind(); - } - - public function valid(): bool - { - return $this->iterator->valid(); - } -} diff --git a/src/Iterator/PsrCacheIterator.php b/src/Iterator/PsrCacheIterator.php index 87c4c6acd..8dbdf863c 100644 --- a/src/Iterator/PsrCacheIterator.php +++ b/src/Iterator/PsrCacheIterator.php @@ -20,12 +20,17 @@ * @template TKey * @template T * - * @extends ProxyIterator + * @implements Iterator */ -final class PsrCacheIterator extends ProxyIterator +final class PsrCacheIterator implements Iterator { private CacheItemPoolInterface $cache; + /** + * @var Iterator + */ + private Iterator $iterator; + private int $key = 0; /** @@ -66,19 +71,19 @@ public function next(): void // This is mostly for iterator_count(). $this->getTupleFromCache($this->key++); - parent::next(); + $this->iterator->next(); } public function rewind(): void { - // No call to parent::rewind() because we do not know if the inner + // No call to $this->iterator->rewind() because we do not know if the inner // iterator can be rewinded or not. $this->key = 0; } public function valid(): bool { - return parent::valid() || $this->cache->hasItem((string) $this->key); + return $this->iterator->valid() || $this->cache->hasItem((string) $this->key); } private function getTupleFromCache(int $key): CacheItemInterface @@ -87,8 +92,8 @@ private function getTupleFromCache(int $key): CacheItemInterface if (false === $item->isHit()) { $item->set([ - parent::key(), - parent::current(), + $this->iterator->key(), + $this->iterator->current(), ]); $this->cache->save($item); diff --git a/src/Iterator/RandomIterator.php b/src/Iterator/RandomIterator.php index dfbe86043..a76936888 100644 --- a/src/Iterator/RandomIterator.php +++ b/src/Iterator/RandomIterator.php @@ -11,7 +11,10 @@ use BadMethodCallException; use Iterator; +use IteratorAggregate; +use loophp\iterators\CachingIteratorAggregate; use ReturnTypeWillChange; +use RuntimeException; use function assert; @@ -24,10 +27,15 @@ * @template TKey * @template T * - * @extends ProxyIterator + * @implements Iterator */ -final class RandomIterator extends ProxyIterator +final class RandomIterator implements Iterator { + /** + * @var IteratorAggregate + */ + private IteratorAggregate $cache; + /** * @var array */ @@ -37,21 +45,18 @@ final class RandomIterator extends ProxyIterator private int $seed; - /** - * @var Iterator - */ - private Iterator $wrappedIterator; - /** * @param Iterator $iterator */ public function __construct(Iterator $iterator, ?int $seed = null) { - $this->iterator = $iterator; $this->seed = $seed ?? random_int(PHP_INT_MIN, PHP_INT_MAX); - $this->wrappedIterator = new ArrayCacheIterator($iterator); + $this->cache = new CachingIteratorAggregate($iterator); } + /** + * @return T + */ #[ReturnTypeWillChange] public function current() { @@ -66,6 +71,9 @@ public function current() return $keyValueTuple[1]; } + /** + * @return TKey + */ #[ReturnTypeWillChange] public function key() { @@ -92,7 +100,7 @@ public function rewind(): void { // @todo: Try to get rid of iterator_count(). $this->indexes = $this->predictableRandomArray( - range(0, iterator_count($this->wrappedIterator) - 1), + range(0, iterator_count($this->cache->getIterator()) - 1), $this->seed ); $this->key = 0; @@ -113,13 +121,13 @@ private function getNextItemAtKey(int $key): array { $i = 0; - $this->wrappedIterator->rewind(); - - while ($this->indexes[$key] !== $i++) { - $this->wrappedIterator->next(); + foreach ($this->cache as $k => $v) { + if ($this->indexes[$key] === $i++) { + return [$k, $v]; + } } - return [$this->wrappedIterator->key(), $this->wrappedIterator->current()]; + throw new RuntimeException('Unable to find key and value.'); } /** diff --git a/src/Iterator/ResourceIterator.php b/src/Iterator/ResourceIterator.php index adfc4ec94..4b3ad8725 100644 --- a/src/Iterator/ResourceIterator.php +++ b/src/Iterator/ResourceIterator.php @@ -11,19 +11,24 @@ use Generator; use InvalidArgumentException; +use Iterator; +use loophp\iterators\ClosureIterator; +use ReturnTypeWillChange; use function is_resource; /** * @internal * - * @template TKey - * @template T - * - * @extends ProxyIterator + * @implements Iterator */ -final class ResourceIterator extends ProxyIterator +final class ResourceIterator implements Iterator { + /** + * @var Iterator + */ + private Iterator $iterator; + /** * @param false|resource $resource */ @@ -53,4 +58,34 @@ static function ($resource) use ($closeResource): Generator { $this->iterator = new ClosureIterator($callback, [$resource]); } + + #[ReturnTypeWillChange] + public function current(): string + { + return $this->iterator->current(); + } + + /** + * @return int + */ + #[ReturnTypeWillChange] + public function key() + { + return $this->iterator->key(); + } + + public function next(): void + { + $this->iterator->next(); + } + + public function rewind(): void + { + $this->iterator->rewind(); + } + + public function valid(): bool + { + return $this->iterator->valid(); + } } diff --git a/src/Iterator/StringIterator.php b/src/Iterator/StringIterator.php index 6e57c404d..13ce462a2 100644 --- a/src/Iterator/StringIterator.php +++ b/src/Iterator/StringIterator.php @@ -10,18 +10,22 @@ namespace loophp\collection\Iterator; use Generator; +use Iterator; use IteratorIterator; +use ReturnTypeWillChange; /** * @internal * - * @template TKey - * @template T of string - * - * @extends ProxyIterator + * @implements Iterator */ -final class StringIterator extends ProxyIterator +final class StringIterator implements Iterator { + /** + * @var Iterator + */ + private Iterator $iterator; + public function __construct(string $data, string $delimiter = '') { $callback = @@ -47,4 +51,34 @@ static function (string $input, string $delimiter): Generator { $this->iterator = new IteratorIterator($callback($data, $delimiter)); } + + #[ReturnTypeWillChange] + public function current(): string + { + return $this->iterator->current(); + } + + /** + * @return int + */ + #[ReturnTypeWillChange] + public function key() + { + return $this->iterator->key(); + } + + public function next(): void + { + $this->iterator->next(); + } + + public function rewind(): void + { + $this->iterator->rewind(); + } + + public function valid(): bool + { + return $this->iterator->valid(); + } } diff --git a/src/Iterator/TypedIterator.php b/src/Iterator/TypedIterator.php index f9c38664c..b705f5bb8 100644 --- a/src/Iterator/TypedIterator.php +++ b/src/Iterator/TypedIterator.php @@ -12,6 +12,8 @@ use Generator; use InvalidArgumentException; use Iterator; +use loophp\iterators\ClosureIterator; +use ReturnTypeWillChange; use function get_class; use function gettype; @@ -23,10 +25,15 @@ * @template TKey * @template T * - * @extends ProxyIterator + * @implements Iterator */ -final class TypedIterator extends ProxyIterator +final class TypedIterator implements Iterator { + /** + * @var Iterator + */ + private Iterator $iterator; + /** * @param Iterator $iterator * @param null|callable(mixed): string $getType @@ -88,4 +95,37 @@ static function (Iterator $iterator) use ($getType): Generator { [$iterator] ); } + + /** + * @return T + */ + #[ReturnTypeWillChange] + public function current() + { + return $this->iterator->current(); + } + + /** + * @return TKey + */ + #[ReturnTypeWillChange] + public function key() + { + return $this->iterator->key(); + } + + public function next(): void + { + $this->iterator->next(); + } + + public function rewind(): void + { + $this->iterator->rewind(); + } + + public function valid(): bool + { + return $this->iterator->valid(); + } } diff --git a/src/Operation/Flatten.php b/src/Operation/Flatten.php index ea8f52b41..8b0e5ce8e 100644 --- a/src/Operation/Flatten.php +++ b/src/Operation/Flatten.php @@ -12,7 +12,7 @@ use Closure; use Generator; use Iterator; -use loophp\collection\Iterator\IterableIterator; +use loophp\iterators\IterableIterator; /** * @immutable diff --git a/src/Operation/Pack.php b/src/Operation/Pack.php index bb3d61c4b..0e1d62698 100644 --- a/src/Operation/Pack.php +++ b/src/Operation/Pack.php @@ -12,6 +12,7 @@ use Closure; use Generator; use Iterator; +use loophp\iterators\PackIterableAggregate; /** * @immutable @@ -28,22 +29,17 @@ final class Pack extends AbstractOperation */ public function __invoke(): Closure { - $mapCallback = + return /** - * @param T $value - * @param TKey $key + * @param Iterator $iterator * - * @return array{0: TKey, 1: T} + * @return Generator */ - static fn ($value, $key): array => [$key, $value]; + static function (Iterator $iterator): Generator { + /** @var PackIterableAggregate $packIterableAggregate */ + $packIterableAggregate = new PackIterableAggregate($iterator); - /** @var Closure(Iterator): Generator $pipe */ - $pipe = Pipe::of()( - Map::of()($mapCallback), - (new Normalize())() - ); - - // Point free style. - return $pipe; + return yield from $packIterableAggregate->getIterator(); + }; } } diff --git a/src/Operation/Product.php b/src/Operation/Product.php index 80aab02f9..346e917d1 100644 --- a/src/Operation/Product.php +++ b/src/Operation/Product.php @@ -13,7 +13,7 @@ use Closure; use Generator; use Iterator; -use loophp\collection\Iterator\IterableIterator; +use loophp\iterators\IterableIterator; /** * @immutable diff --git a/src/Operation/Transpose.php b/src/Operation/Transpose.php index efa2930a2..b504f1782 100644 --- a/src/Operation/Transpose.php +++ b/src/Operation/Transpose.php @@ -12,7 +12,7 @@ use Closure; use Generator; use Iterator; -use loophp\collection\Iterator\IterableIterator; +use loophp\iterators\IterableIterator; use MultipleIterator; /** diff --git a/src/Operation/Unpack.php b/src/Operation/Unpack.php index dc7f6be79..7faa4c5d4 100644 --- a/src/Operation/Unpack.php +++ b/src/Operation/Unpack.php @@ -12,7 +12,7 @@ use Closure; use Generator; use Iterator; -use loophp\collection\Iterator\IterableIterator; +use loophp\iterators\IterableIterator; /** * @immutable diff --git a/src/Operation/Zip.php b/src/Operation/Zip.php index 76b08a62e..87bfb97d6 100644 --- a/src/Operation/Zip.php +++ b/src/Operation/Zip.php @@ -13,7 +13,7 @@ use Closure; use Generator; use Iterator; -use loophp\collection\Iterator\IterableIterator; +use loophp\iterators\IterableIterator; use MultipleIterator; /**