Skip to content

Commit 5e201b4

Browse files
committed
CollectionOfCaster
1 parent b58f187 commit 5e201b4

File tree

5 files changed

+33
-6
lines changed

5 files changed

+33
-6
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ composer require "fab2s/laravel-dt0"
1616

1717
`Laravel Dt0` only adds Validation implementation and model attribute casting to `Dt0`. All other features will work exactly the same. Have a look at [`Dt0`](https://github.com/fab2s/dt0) to find out more.
1818

19+
## Caster
20+
21+
In addition to [`Dt0 casters`](https://github.com/fab2s/dt0/tree/main/src/docs/casters.md), `Laravel Dt0` adds a [`CollectionOfCaster`](./src/Caster/CollectionOfCaster.php) which can be used to strongly type a Laravel `Collection`:
22+
23+
````php
24+
#[Cast(in: new CollectionOfCaster(MyDt0::class))] // Dt0|UnitEnum|ScalarType|string
25+
public readonly Collection $prop;
26+
````
27+
28+
It can be used as an inspiration to cast into more types.
29+
1930
## Validation
2031

2132
`Laravel Dt0` is able to leverage the full power of Laravel validation on each of its public properties. The validation is performed on the input data prior to any property casting or instantiation.

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
],
3030
"require": {
3131
"php": "^8.1",
32-
"fab2s/dt0": "dev-main",
32+
"fab2s/dt0": "^0.0.1",
3333
"illuminate/translation": "^10.0|^11.0",
3434
"illuminate/validation": "^10.0|^11.0"
3535
},

src/Caster/CollectionOfCaster.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
use fab2s\Dt0\Caster\ScalarType;
1616
use fab2s\Dt0\Dt0;
1717
use fab2s\Dt0\Exception\CasterException;
18+
use fab2s\Dt0\Exception\Dt0Exception;
1819
use fab2s\Dt0\Property\Property;
1920
use Illuminate\Support\Collection;
21+
use JsonException;
2022

2123
class CollectionOfCaster implements CasterInterface
2224
{
@@ -41,13 +43,17 @@ public function __construct(
4143
}
4244

4345
if (! $logicalType) {
44-
throw new CasterException('[' . Dt0::classBasename(static::class) . "] $type is not an ArrayType nor a ScalarType");
46+
throw new CasterException('[' . Dt0::classBasename(static::class) . "] $type is not a supported type");
4547
}
4648

4749
$this->logicalType = $logicalType;
4850
$this->scalarCaster = $this->logicalType instanceof ScalarType ? new ScalarCaster($this->logicalType) : null;
4951
}
5052

53+
/**
54+
* @throws Dt0Exception
55+
* @throws JsonException
56+
*/
5157
public function cast(mixed $value): ?Collection
5258
{
5359
if (! is_iterable($value)) {
@@ -58,9 +64,11 @@ public function cast(mixed $value): ?Collection
5864

5965
foreach ($value as $item) {
6066
$result->push(match ($this->logicalType) {
61-
ArrayType::DT0 => $this->type::tryFrom($item),
62-
ArrayType::ENUM => Property::tryEnum($this->type, $item),
63-
default => $this->scalarCaster->cast($item),
67+
ArrayType::DT0 => $this->type::from($item),
68+
ArrayType::ENUM => Property::enumFrom($this->type, $item),
69+
default => $this->scalarCaster->cast($item) ?? throw (new CasterException('Could not cast array item to scalar type ' . $this->logicalType->value))->setContext([
70+
'item' => $item,
71+
]),
6472
});
6573
}
6674

src/Validator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
class Validator implements ValidatorInterface
1818
{
19-
public array $rules = [];
19+
protected array $rules = [];
2020

2121
/**
2222
* @throws ValidationException

tests/Caster/CollectionOfCasterTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Exception;
1313
use fab2s\Dt0\Caster\ScalarType;
1414
use fab2s\Dt0\Exception\CasterException;
15+
use fab2s\Dt0\Exception\Dt0Exception;
1516
use fab2s\Dt0\Laravel\Caster\CollectionOfCaster;
1617
use fab2s\Dt0\Laravel\Tests\Artifacts\DumbDt0;
1718
use fab2s\Dt0\Laravel\Tests\TestCase;
@@ -37,6 +38,13 @@ public function test_exception(): void
3738
new CollectionOfCaster('NotAType');
3839
}
3940

41+
public function test_scalar_exception(): void
42+
{
43+
$this->expectException(Dt0Exception::class);
44+
$caster = new CollectionOfCaster(ScalarType::bool);
45+
$caster->cast([[]]);
46+
}
47+
4048
public static function castProvider(): array
4149
{
4250
return [

0 commit comments

Comments
 (0)