Skip to content

Commit

Permalink
Add Custom hybid type.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Jun 7, 2022
1 parent 6b25899 commit b115a4c
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/TG.php
Expand Up @@ -84,6 +84,19 @@ public static function compound(TypeGenerator $t1, TypeGenerator $t2): Compound
return Compound::new($t1, $t2);
}

/**
* @template V
*
* @param TypeGenerator<V> $type
* @param Closure(TypeGenerator<V>): V $generator
*
* @return Custom<V>
*/
public static function custom(TypeGenerator $type, Closure $generator): Custom
{
return Custom::new($type, $generator);
}

public static function datetime(?DateTimeInterface $from = null, ?DateTimeInterface $to = null): DateTimeType
{
return DateTimeType::new($from, $to);
Expand Down
84 changes: 84 additions & 0 deletions src/Types/Hybrid/Custom.php
@@ -0,0 +1,84 @@
<?php

/**
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

declare(strict_types=1);

namespace loophp\TypedGenerators\Types\Hybrid;

use Closure;
use Iterator;
use loophp\TypedGenerators\Types\TypeGenerator;

/**
* @template T
*
* @implements TypeGenerator<T>
*/
final class Custom implements TypeGenerator
{
/**
* @var Closure(TypeGenerator<T>): T
*/
private Closure $generator;

/**
* @var TypeGenerator<T>
*/
private TypeGenerator $type;

/**
* @param TypeGenerator<T> $type
* @param Closure(TypeGenerator<T>): T $generator
*/
public function __construct(TypeGenerator $type, Closure $generator)
{
$this->type = $type;
$this->generator = $generator;
}

/**
* @return T
*/
public function __invoke()
{
return $this->identity(($this->generator)($this->type));
}

/**
* @return Iterator<int, T>
*/
public function getIterator(): Iterator
{
// @phpstan-ignore-next-line
while (true) {
yield $this->__invoke();
}
}

/**
* @param T $input
*
* @return T
*/
public function identity($input)
{
return $this->type->identity($input);
}

/**
* @template V
*
* @param TypeGenerator<V> $type
* @param Closure(TypeGenerator<V>): V $generator
*
* @return Custom<V>
*/
public static function new(TypeGenerator $type, Closure $generator): self
{
return new self($type, $generator);
}
}
9 changes: 9 additions & 0 deletions tests/unit/TGTest.php
Expand Up @@ -84,6 +84,15 @@ public function typeProvider()
'class' => Compound::class,
];

yield [
'method' => 'custom',
'arguments' => [
new StringType(),
static fn (): string => 'hello',
],
'class' => Custom::class,
];

yield [
'method' => 'datetime',
'arguments' => [],
Expand Down

0 comments on commit b115a4c

Please sign in to comment.