Skip to content

Commit 9519d03

Browse files
authored
Merge pull request #28 from refactor-ring/backend-enum-arrays
Added support for an array containing a backed enum type
2 parents 5a2db0a + fa913ff commit 9519d03

File tree

5 files changed

+76
-18
lines changed

5 files changed

+76
-18
lines changed

src/Internal/RClass.php

+15-17
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
<?php declare(strict_types=1);
1+
<?php
2+
3+
declare(strict_types=1);
24

35
namespace Square\Pjson\Internal;
46

57
use BackedEnum;
68
use ReflectionClass;
79
use Square\Pjson\FromJsonData;
8-
use UnitEnum;
910
use Square\Pjson\JsonSerialize;
1011
use Square\Pjson\ToJsonData;
12+
use UnitEnum;
1113

1214
class RClass
1315
{
@@ -27,13 +29,13 @@ protected function __construct($class)
2729
}
2830
}
2931

30-
public static function make($class) : RClass
32+
public static function make($class): RClass
3133
{
3234
if (is_object($class)) {
3335
$class = get_class($class);
3436
}
3537

36-
if (!array_key_exists($class, self::$cache)) {
38+
if (! array_key_exists($class, self::$cache)) {
3739
self::$cache[$class] = new self($class);
3840
}
3941

@@ -45,37 +47,35 @@ public function getProperties()
4547
return $this->props;
4648
}
4749

48-
public function source() : ReflectionClass
50+
public function source(): ReflectionClass
4951
{
5052
return $this->rc;
5153
}
5254

53-
public function isBackedEnum() : bool
55+
public function isBackedEnum(): bool
5456
{
55-
return $this->rc->implementsInterface(BackedEnum::class);
57+
return interface_exists(BackedEnum::class) && $this->rc->implementsInterface(BackedEnum::class);
5658
}
5759

58-
public function isEnum() : bool
60+
public function isEnum(): bool
5961
{
6062
return $this->rc->implementsInterface(UnitEnum::class);
6163
}
6264

63-
public function isSimpleEnum() : bool
65+
public function isSimpleEnum(): bool
6466
{
65-
return $this->isEnum() && !$this->isBackedEnum();
67+
return $this->isEnum() && ! $this->isBackedEnum();
6668
}
6769

68-
public function isMethodStatic(string $methodName) : bool
70+
public function isMethodStatic(string $methodName): bool
6971
{
7072
return $this->rc->getMethod($methodName)->isStatic();
7173
}
7274

7375
/**
7476
* True if the type either implements the FromJsonData interface or directly uses the JsonSerialize trait
75-
*
76-
* @return boolean
7777
*/
78-
public function readsFromJson() : bool
78+
public function readsFromJson(): bool
7979
{
8080
$traits = class_uses($this->rc->getName());
8181

@@ -84,10 +84,8 @@ public function readsFromJson() : bool
8484

8585
/**
8686
* True if the type either implements the ToJsonData interface or directly uses the JsonSerialize trait
87-
*
88-
* @return boolean
8987
*/
90-
public function writesToJson() : bool
88+
public function writesToJson(): bool
9189
{
9290
$traits = class_uses($this->rc->getName());
9391

src/Json.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,15 @@ public function retrieveValue(?array $data, ?ReflectionNamedType $type = null)
8888
return $data;
8989
}
9090
if (!class_exists($typename) && $typename === 'array' && isset($this->type)) {
91-
return is_null($data) ? $data : array_map(fn ($d) => $this->type::fromJsonData($d), $data);
91+
if (is_null($data)) {
92+
return $data;
93+
}
94+
95+
if (RClass::make($this->type)->isBackedEnum()) {
96+
return array_map(fn ($d) => $this->type::from($d), $data);
97+
}
98+
99+
return array_map(fn ($d) => $this->type::fromJsonData($d), $data);
92100
}
93101

94102
// Deal with collections / Traversable classes

tests/Definitions/StatusList.php

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Square\Pjson\Tests\Definitions;
4+
5+
use Square\Pjson\Json;
6+
use Square\Pjson\JsonSerialize;
7+
8+
class StatusList
9+
{
10+
use JsonSerialize;
11+
12+
#[Json('status_list', type: Status::class)]
13+
public array $statusList;
14+
}

tests/php81/Php81DeSerializationTest.php

+28
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Square\Pjson\Tests\Definitions\DTO;
77
use Square\Pjson\Tests\Definitions\Size;
88
use Square\Pjson\Tests\Definitions\Status;
9+
use Square\Pjson\Tests\Definitions\StatusList;
910
use Square\Pjson\Tests\Definitions\Widget;
1011

1112
final class Php81DeSerializationTest extends TestCase
@@ -110,4 +111,31 @@ public function testEnum()
110111
],
111112
], $this->export($w));
112113
}
114+
115+
public function testBackedEnumArray()
116+
{
117+
$w = StatusList::fromJsonString('{
118+
"status_list": ["ON", "OFF", "ON"]
119+
}');
120+
$this->assertEquals([
121+
"@class" => StatusList::class,
122+
"statusList" => [
123+
0 => [
124+
"@class" => Status::class,
125+
"name" => "ON",
126+
"value" => "ON",
127+
],
128+
1 => [
129+
"@class" => Status::class,
130+
"name" => "OFF",
131+
"value" => "OFF",
132+
],
133+
2 => [
134+
"@class" => Status::class,
135+
"name" => "ON",
136+
"value" => "ON",
137+
]
138+
],
139+
], $this->export($w));
140+
}
113141
}

tests/php81/Php81SerializationTest.php

+10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Square\Pjson\Tests\Definitions\DTO;
66
use Square\Pjson\Tests\Definitions\Size;
77
use Square\Pjson\Tests\Definitions\Status;
8+
use Square\Pjson\Tests\Definitions\StatusList;
89
use Square\Pjson\Tests\Definitions\Widget;
910

1011
final class Php81SerializationTest extends TestCase
@@ -36,4 +37,13 @@ public function testEnum()
3637
"size": "big"
3738
}')), $w->toJson());
3839
}
40+
41+
public function testBackedEnumArray()
42+
{
43+
$w = new StatusList();
44+
$w->statusList = [Status::ON, Status::OFF, Status::ON];
45+
$this->assertEquals(json_encode(json_decode('{
46+
"status_list": ["ON", "OFF", "ON"]
47+
}')), $w->toJson());
48+
}
3949
}

0 commit comments

Comments
 (0)