Skip to content

Commit

Permalink
Add new typed factories.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Jul 6, 2020
1 parent 5a727ae commit 615189f
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 106 deletions.
41 changes: 41 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@

namespace loophp\collection;

use Generator;
use loophp\collection\Contract\Base as BaseInterface;
use loophp\collection\Contract\Collection as CollectionInterface;
use loophp\collection\Iterator\ClosureIterator;
use loophp\collection\Iterator\IterableIterator;
use loophp\collection\Iterator\ResourceIterator;
use loophp\collection\Iterator\StringIterator;
use loophp\collection\Operation\Append;
use loophp\collection\Operation\Apply;
use loophp\collection\Operation\Chunk;
Expand Down Expand Up @@ -190,6 +195,42 @@ public function frequency(): BaseInterface
return $this->run(new Frequency());
}

public static function fromCallable(callable $callable, ...$parameters): CollectionInterface
{
return new self(
static function () use ($callable, $parameters): Generator {
return yield from new ClosureIterator($callable, ...$parameters);
}
);
}

public static function fromIterable(iterable $iterable): CollectionInterface
{
return new self(
static function () use ($iterable): Generator {
return yield from new IterableIterator($iterable);
}
);
}

public static function fromResource($resource): CollectionInterface
{
return new self(
static function () use ($resource): Generator {
return yield from new ResourceIterator($resource);
}
);
}

public static function fromString(string $string, string $delimiter = ''): CollectionInterface
{
return new self(
static function () use ($string, $delimiter): Generator {
return yield from new StringIterator($string, $delimiter);
}
);
}

public function get($key, $default = null)
{
return $this->transform(new Get($key, $default));
Expand Down
19 changes: 19 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,25 @@ interface Collection extends
*/
public static function empty(): Collection;

/**
* @param mixed ...$parameters
*
* @return \loophp\collection\Contract\Collection
*/
public static function fromCallable(callable $callable, ...$parameters): Collection;

/**
* @param iterable<mixed> $iterable
*/
public static function fromIterable(iterable $iterable): Collection;

/**
* @param resource $resource
*/
public static function fromResource($resource): Collection;

public static function fromString(string $string, string $delimiter = ''): Collection;

/**
* Create a collection with the data.
*
Expand Down
61 changes: 11 additions & 50 deletions src/Iterator/ClosureIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@

namespace loophp\collection\Iterator;

use Closure;
use Generator;
use Iterator;
use OuterIterator;

/**
* Class ClosureIterator.
*
* @implements Iterator<mixed>
*/
final class ClosureIterator implements Iterator
final class ClosureIterator extends ProxyIterator implements Iterator, OuterIterator
{
/**
* @var array<mixed>
* @var array<int, mixed>
*/
private $arguments;

Expand All @@ -25,7 +27,7 @@ final class ClosureIterator implements Iterator
private $callable;

/**
* @var Generator<Generator<mixed>>|null
* @var Closure
*/
private $generator;

Expand All @@ -38,49 +40,16 @@ public function __construct(callable $callable, ...$arguments)
{
$this->callable = $callable;
$this->arguments = $arguments;
}

/**
* {@inheritdoc}
*/
public function current()
{
return $this->getGenerator()->current();
}
$this->generator = static function (callable $callable, array $arguments): Generator {
return yield from ($callable)(...$arguments);
};

/**
* {@inheritdoc}
*
* @return int|string
*/
public function key()
{
return $this->getGenerator()->key();
}

/**
* {@inheritdoc}
*
* @return void
*/
public function next()
{
$this->getGenerator()->next();
$this->iterator = $this->getGenerator();
}

public function rewind(): void
{
$this->generator = null;
}

/**
* {@inheritdoc}
*
* @return bool
*/
public function valid()
{
return $this->getGenerator()->valid();
$this->iterator = $this->getGenerator();
}

/**
Expand All @@ -90,14 +59,6 @@ public function valid()
*/
private function getGenerator(): Generator
{
if (null === $this->generator) {
$this->generator = (
static function (callable $callable, array $arguments): Generator {
yield from ($callable)(...$arguments);
}
)($this->callable, $this->arguments);
}

return $this->generator;
return ($this->generator)($this->callable, $this->arguments);
}
}
61 changes: 5 additions & 56 deletions src/Iterator/IterableIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,15 @@

use Generator;
use Iterator;
use OuterIterator;

/**
* Class IterableIterator.
*
* @implements Iterator<mixed>
*/
final class IterableIterator implements Iterator
final class IterableIterator extends ProxyIterator implements Iterator, OuterIterator
{
/**
* @var \loophp\collection\Iterator\ClosureIterator
*/
private $iterator;

/**
* IterableIterator constructor.
*
Expand All @@ -27,59 +23,12 @@ final class IterableIterator implements Iterator
public function __construct(iterable $iterable)
{
$this->iterator = new ClosureIterator(
static function () use ($iterable): Generator {
static function (iterable $iterable): Generator {
foreach ($iterable as $key => $value) {
yield $key => $value;
}
}
},
$iterable
);
}

/**
* {@inheritdoc}
*/
public function current()
{
return $this->iterator->current();
}

/**
* {@inheritdoc}
*
* @return int|string
*/
public function key()
{
return $this->iterator->key();
}

/**
* {@inheritdoc}
*
* @return void
*/
public function next()
{
$this->iterator->next();
}

/**
* {@inheritdoc}
*
* @return void
*/
public function rewind()
{
$this->iterator->rewind();
}

/**
* {@inheritdoc}
*
* @return bool
*/
public function valid()
{
return $this->iterator->valid();
}
}
55 changes: 55 additions & 0 deletions src/Iterator/ProxyIterator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Iterator;

use Generator;
use Iterator;

abstract class ProxyIterator
{
/**
* @var Generator<mixed>|\loophp\collection\Iterator\ClosureIterator
*/
protected $iterator;

/**
* @return mixed
*/
public function current()
{
return $this->iterator->current();
}

/**
* @return Iterator<mixed>
*/
public function getInnerIterator(): Iterator
{
return $this->iterator;
}

/**
* @return mixed
*/
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();
}
}
38 changes: 38 additions & 0 deletions src/Iterator/ResourceIterator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Iterator;

use Generator;
use Iterator;
use OuterIterator;

/**
* @implements Iterator<mixed>
*/
final class ResourceIterator extends ProxyIterator implements Iterator, OuterIterator
{
/**
* ResourceIterator constructor.
*
* @param resource $resource
*/
public function __construct($resource)
{
$closure =
/**
* @param resource $resource
*/
static function ($resource): Generator {
while (false !== $chunk = fgetc($resource)) {
yield $chunk;
}
};

$this->iterator = new ClosureIterator(
$closure,
$resource
);
}
}
Loading

0 comments on commit 615189f

Please sign in to comment.