Skip to content

Commit

Permalink
feat: LazyList, not yet used. (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
priyadi authored Feb 17, 2024
1 parent f11dc43 commit de05912
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/ListInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper;

/**
* @template TKey of int
* @template TValue
* @extends \IteratorAggregate<TKey,TValue>
* @extends \ArrayAccess<TKey,TValue>
*/
interface ListInterface extends \ArrayAccess, \IteratorAggregate, \Countable
{
}
115 changes: 115 additions & 0 deletions src/Transformer/Model/LazyList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Transformer\Model;

use Rekalogika\Mapper\Context\Context;
use Rekalogika\Mapper\ListInterface;
use Rekalogika\Mapper\MainTransformer\MainTransformerInterface;
use Rekalogika\Mapper\Transformer\ArrayLikeMetadata\ArrayLikeMetadata;
use Rekalogika\Mapper\Transformer\MainTransformerAwareTrait;
use Rekalogika\Mapper\Transformer\Trait\ArrayLikeTransformerTrait;

/**
* Discards source key, and use incremental integer key in the target.
*
* @template TValue
* @implements ListInterface<int,TValue>
* @internal
*/
final class LazyList implements ListInterface
{
use MainTransformerAwareTrait;
use ArrayLikeTransformerTrait;

/**
* @var array<int,TValue>
*/
private array $cachedData = [];
private bool $isCached = false;

/**
* @param (\Traversable<mixed,mixed>&\ArrayAccess<mixed,mixed>&\Countable)|array<int|string,mixed> $source
*/
public function __construct(
private (\Traversable&\ArrayAccess&\Countable)|array $source,
MainTransformerInterface $mainTransformer,
private ArrayLikeMetadata $metadata,
private Context $context,
) {
$this->mainTransformer = $mainTransformer;
}

public function offsetExists(mixed $offset): bool
{
return isset($this->cachedData[$offset]) || isset($this->source[$offset]);
}

public function offsetGet(mixed $offset): mixed
{
if (!$this->isCached) {
foreach($this->getIterator() as $i);
}

return $this->cachedData[$offset];
}

public function offsetSet(mixed $offset, mixed $value): void
{
throw new \BadMethodCallException('LazyArray is immutable.');
}

public function offsetUnset(mixed $offset): void
{
throw new \BadMethodCallException('LazyArray is immutable.');
}

public function getIterator(): \Traversable
{
if ($this->isCached) {
yield from $this->cachedData;

return;
}

$i = 0;

/**
* @var mixed $sourceMemberValue
*/
foreach ($this->source as $sourceMemberKey => $sourceMemberValue) {
/**
* @var TValue $value
*/
[, $value] = $this->transformMember(
sourceMemberKey: $sourceMemberKey,
sourceMemberValue: $sourceMemberValue,
metadata: $this->metadata,
context: $this->context,
);

$this->cachedData[$i] = $value;

yield $value;

$i++;
}

$this->isCached = true;
}

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

0 comments on commit de05912

Please sign in to comment.