Skip to content

Commit

Permalink
Merge pull request #11 from EventSaucePHP/feature/hydrate-list-of-obj…
Browse files Browse the repository at this point in the history
…ects

Fixed #9: Added ability to map a list of payloads to objects.
  • Loading branch information
frankdejonge authored Apr 1, 2022
2 parents 930bb09 + 602ea4a commit bee0b2d
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.0] - 2022-04-01

### Added

- Added `hydrateObjects`; a way to hydrate a list of objects in one go

## [0.1.0] - 2022-01-03

### Added
Expand Down
42 changes: 42 additions & 0 deletions src/ListOfObjects.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace EventSauce\ObjectHydrator;

use ArrayIterator;
use IteratorAggregate;
use Traversable;
use function iterator_to_array;

/**
* @template T
*/
class ListOfObjects implements IteratorAggregate
{
public function __construct(private iterable $objects)
{
}



/**
* @return Traversable<T>
*/
public function getIterator(): Traversable
{
return $this->objects instanceof Traversable
? $this->objects
: new ArrayIterator($this->objects);
}

/**
* @return T[]
*/
public function toArray(): array
{
return $this->objects instanceof Traversable
? iterator_to_array($this->objects, false)
: (array) $this->objects;
}
}
21 changes: 21 additions & 0 deletions src/ObjectHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace EventSauce\ObjectHydrator;

use Generator;
use Throwable;
use function array_key_exists;
use function count;
Expand Down Expand Up @@ -86,4 +87,24 @@ public function hydrateObject(string $className, array $payload): object
throw UnableToHydrateObject::dueToError($className, $exception);
}
}

/**
* @param class-string<T> $className
* @param iterable<array> $payloads;
*
* @return ListOfObjects<T>
*/
public function hydrateObjects(string $className, iterable $payloads): ListOfObjects
{
$generator = $this->doHydrateObjects($className, $payloads);

return new ListOfObjects($generator);
}

private function doHydrateObjects(string $className, iterable $payloads): Generator
{
foreach ($payloads as $payload) {
yield $this->hydrateObject($className, $payload);
}
}
}
28 changes: 28 additions & 0 deletions src/ObjectHydratorTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,34 @@ public function properties_can_be_mapped_from_a_specific_key(): void
self::assertEquals('Frank', $object->name);
}

/**
* @test
*/
public function mapping_to_a_list_of_objects(): void
{
$hydrator = $this->createObjectHydrator();
$input = [['my_name' => 'Frank'], ['my_name' => 'Renske']];

$objects = $hydrator->hydrateObjects(ClassWithMappedStringProperty::class, $input);

self::assertContainsOnlyInstancesOf(ClassWithMappedStringProperty::class, $objects);
}

/**
* @test
*/
public function mapping_to_an_array_of_objects(): void
{
$hydrator = $this->createObjectHydrator();
$input = [['my_name' => 'Frank'], ['my_name' => 'Renske']];

$objects = $hydrator->hydrateObjects(ClassWithMappedStringProperty::class, $input)->toArray();

self::assertIsArray($objects);
self::assertCount(2, $objects);
self::assertContainsOnlyInstancesOf(ClassWithMappedStringProperty::class, $objects);
}

/**
* @test
*/
Expand Down

0 comments on commit bee0b2d

Please sign in to comment.