Skip to content

Commit d3f48da

Browse files
committed
feat: add support of enum
1 parent a9b5fbf commit d3f48da

File tree

8 files changed

+70
-5
lines changed

8 files changed

+70
-5
lines changed

src/Descriptors/Values.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44

55
use Ark4ne\JsonApi\Descriptors\Relations\RelationMany;
66
use Ark4ne\JsonApi\Descriptors\Relations\RelationOne;
7-
use Ark4ne\JsonApi\Descriptors\Values\{
8-
ValueArray,
7+
use Ark4ne\JsonApi\Descriptors\Values\{ValueArray,
98
ValueBool,
109
ValueDate,
10+
ValueEnum,
1111
ValueFloat,
1212
ValueInteger,
1313
ValueMixed,
14-
ValueString
15-
};
14+
ValueString};
1615
use Closure;
1716

1817
/**
@@ -89,4 +88,14 @@ protected function mixed(null|string|Closure $attribute = null): ValueMixed
8988
{
9089
return new ValueMixed($attribute);
9190
}
91+
92+
/**
93+
* @param null|string|Closure(T):mixed $attribute
94+
*
95+
* @return \Ark4ne\JsonApi\Descriptors\Values\ValueEnum<T>
96+
*/
97+
protected function enum(null|string|Closure $attribute = null): ValueEnum
98+
{
99+
return new ValueEnum($attribute);
100+
}
92101
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Ark4ne\JsonApi\Descriptors\Values;
4+
5+
use BackedEnum;
6+
use UnitEnum;
7+
8+
/**
9+
* @template T
10+
* @extends Value<T>
11+
*/
12+
class ValueEnum extends Value
13+
{
14+
protected function value(mixed $of): mixed
15+
{
16+
if ($of instanceof BackedEnum) return $of->value;
17+
if ($of instanceof UnitEnum) return $of->name;
18+
19+
return $of;
20+
}
21+
}

tests/Feature/SchemaTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class SchemaTest extends FeatureTestCase
1414
public function testSchema()
1515
{
1616
$user = new Skeleton(UserResource::class, 'user', ['name', 'email', 'only-with-fields']);
17-
$post = new Skeleton(PostResource::class, 'post', ['title', 'content']);
17+
$post = new Skeleton(PostResource::class, 'post', ['state', 'title', 'content']);
1818
$comment = new Skeleton(CommentResource::class, 'comment', ['content']);
1919

2020
$user->relationships['posts'] = $post;

tests/Unit/Descriptors/ValueTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Ark4ne\JsonApi\Descriptors\Values\ValueArray;
77
use Ark4ne\JsonApi\Descriptors\Values\ValueBool;
88
use Ark4ne\JsonApi\Descriptors\Values\ValueDate;
9+
use Ark4ne\JsonApi\Descriptors\Values\ValueEnum;
910
use Ark4ne\JsonApi\Descriptors\Values\ValueFloat;
1011
use Ark4ne\JsonApi\Descriptors\Values\ValueInteger;
1112
use Ark4ne\JsonApi\Descriptors\Values\ValueMixed;
@@ -67,6 +68,8 @@ public static function values()
6768
'date.2' => [ValueDate::class, 1640995200, '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
6869
'date.3' => [ValueDate::class, new DateTime("@1640995200"), '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
6970
'date.4' => [ValueDate::class, new Carbon("@1640995200"), '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
71+
'enum.0' => [ValueEnum::class, TestUnitEnum::A, 'A', null],
72+
'enum.1' => [ValueEnum::class, TestBackendEnum::A, 'aaa', null],
7073
];
7174
}
7275

@@ -243,3 +246,15 @@ private function throughRetrieverTest(&$model, \Closure $missing, \Closure $upda
243246
$this->assertEquals($expected, $check($valueClosureRetriever));
244247
}
245248
}
249+
250+
enum TestBackendEnum: string
251+
{
252+
case A = 'aaa';
253+
case B = 'bbb';
254+
case C = 'ccc';
255+
}
256+
enum TestUnitEnum {
257+
case A;
258+
case B;
259+
case C;
260+
}

tests/app/Enums/State.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Test\app\Enums;
4+
5+
enum State: int
6+
{
7+
case Draft = 0;
8+
case Published = 1;
9+
}

tests/app/Http/Resources/PostResource.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ protected function toType(Request $request): string
1919
protected function toAttributes(Request $request): iterable
2020
{
2121
return [
22+
'state' => $this->enum(),
2223
'title' => $this->string(),
2324
'content' => $this->string()->whenInFields(),
2425
];

tests/app/Models/Post.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
use Illuminate\Database\Eloquent\Model;
77
use Illuminate\Database\Eloquent\Relations\BelongsTo;
88
use Illuminate\Database\Eloquent\Relations\HasMany;
9+
use Test\app\Enums\State;
910
use Test\app\Factories\PostFactory;
1011

1112
/**
1213
* @property int $id
14+
* @property State $state
1315
* @property string $title
1416
* @property string $content
1517
* @property \DateTimeInterface $created_at
@@ -22,6 +24,11 @@ class Post extends Model
2224
{
2325
use HasFactory;
2426

27+
/** @var array<string, mixed> */
28+
protected $casts = [
29+
'state' => State::class,
30+
];
31+
2532
protected static function newFactory(): PostFactory
2633
{
2734
return new PostFactory();

tests/app/migrations.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public function tables()
1818
},
1919
'posts' => function (Blueprint $table) {
2020
$table->id();
21+
$table->boolean('state')
22+
->default(false)
23+
->comment('0: draft, 1: published');
2124
$table->string('title');
2225
$table->string('content');
2326
$table->timestamps();

0 commit comments

Comments
 (0)