/shaku

Tool to automatically generate type-safe Collection and CollectionIterator classes

Primary LanguagePHPOtherNOASSERTION

Shaku, the Collection Generator

shaku can automatically generate type-safe Collection and CollectionIterator classes.

Installation

The recommended way to use this tool is a PHP Archive (PHAR):

$ wget https://phar.phpunit.de/shaku.phar

$ php shaku.phar --version

Furthermore, it is recommended to use Phive for installing and updating the tool dependencies of your project.

Alternatively, you may use Composer to download and install this tool as well as its dependencies. This is not recommended, though.

Usage

Consider you have a class named Value (declared in src/Value.php) and need a type-safe ValueCollection for objects of this type:

namespace vendor;

final class Value
{
    // ...
}

Generating the Collection and CollectionIterator

You can use this tool to automatically generate the code for the ValueCollection and ValueCollectionIterator class like so:

$ php shaku.phar --immutable vendor Value src

The above results in the generation of the code shown below:

<?php declare(strict_types=1);
namespace vendor;

final class ValueCollection implements \Countable, \IteratorAggregate
{
    /**
     * @var Value[]
     */
    private $items = [];

    public static function fromArray(array $items): self
    {
        $collection = new self;

        foreach ($items as $item) {
            $collection->add($item);
        }

        return $collection;
    }

    public static function fromList(Value ...$items): self
    {
        return self::fromArray($items);
    }

    private function __construct()
    {
    }

    private function add(Value $item): void
    {
        $this->items[] = $item;
    }

    /**
     * @return Value[]
     */
    public function toArray(): array
    {
        return $this->items;
    }

    public function getIterator(): ValueCollectionIterator
    {
        return new ValueCollectionIterator($this);
    }

    public function count(): int
    {
        return \count($this->items);
    }

    public function isEmpty(): bool
    {
        return empty($this->items);
    }

    public function contains(Value $item): bool
    {
        foreach ($this->items as $_item) {
            if ($_item === $item) {
                return true;
            }
        }

        return false;
    }
}
<?php declare(strict_types=1);
namespace vendor;

final class ValueCollectionIterator implements \Countable, \Iterator
{
    /**
     * @var Value[]
     */
    private $items;

    /**
     * @var int
     */
    private $position;

    public function __construct(ValueCollection $collection)
    {
        $this->items = $collection->toArray();
    }

    public function count(): int
    {
        return \iterator_count($this);
    }

    public function rewind(): void
    {
        $this->position = 0;
    }

    public function valid(): bool
    {
        return $this->position < \count($this->items);
    }

    public function key(): int
    {
        return $this->position;
    }

    public function current(): Value
    {
        return $this->items[$this->position];
    }

    public function next(): void
    {
        $this->position++;
    }
}

Using the generated Collection and CollectionIterator

Creating a collection from an array of objects

$values = ValueCollection::fromArray([new Value, new Value]);

Creating a collection from a list of objects

$values = ValueCollection::fromList(new Value, new Value);

Creating an empty collection and adding objects to it

$values = new ValueCollection;

$values->add(new Value);
$values->add(new Value);

Shaku?

This tool is named after "Shaku, the Collector", Copyright Blizzard Entertainment, Inc.