diff --git a/src/Psl/Type/Internal/ShapeType.php b/src/Psl/Type/Internal/ShapeType.php index bae26522..65b2aad6 100644 --- a/src/Psl/Type/Internal/ShapeType.php +++ b/src/Psl/Type/Internal/ShapeType.php @@ -8,6 +8,7 @@ use Psl\Type; use Psl\Type\Exception\AssertException; use Psl\Type\Exception\CoercionException; +use stdClass; use function array_diff_key; use function array_filter; @@ -51,6 +52,10 @@ public function __construct( */ public function coerce(mixed $value): array { + if ($value instanceof stdClass) { + $value = (array) $value; + } + // To whom reads this: yes, I hate this stuff as passionately as you do :-) if (! is_array($value)) { // Fallback to slow implementation - unhappy path diff --git a/tests/unit/Type/ShapeTypeTest.php b/tests/unit/Type/ShapeTypeTest.php index 7366dbbe..43809d17 100644 --- a/tests/unit/Type/ShapeTypeTest.php +++ b/tests/unit/Type/ShapeTypeTest.php @@ -120,6 +120,17 @@ private function validCoercions(): iterable ]], ]; + yield 'stdClass containing a valid shape' => [ + (object) ['name' => 'saif', 'articles' => new Collection\Vector([ + ['title' => 'Foo', 'content' => 'Bar', 'likes' => 0, 'dislikes' => 5], + ['title' => 'Baz', 'content' => 'Qux', 'likes' => 13, 'dislikes' => 3], + ])], + ['name' => 'saif', 'articles' => [ + ['title' => 'Foo', 'content' => 'Bar', 'likes' => 0], + ['title' => 'Baz', 'content' => 'Qux', 'likes' => 13], + ]], + ]; + yield [ ['name' => 'saif', 'articles' => new Collection\Vector([ ['title' => 'Foo', 'content' => 'Bar', 'likes' => 0, 'dislikes' => 5], @@ -150,6 +161,9 @@ public function getInvalidCoercions(): iterable yield [['name' => 'saif', 'articles' => [ ['title' => 'biz', 'content' => 'foo', 'upvotes' => 4] // 'likes' replaced by 'upvotes' ]]]; + yield [(object) ['name' => 'saif', 'articles' => [ + ['title' => 'biz', 'content' => 'foo', 'upvotes' => 4] // 'likes' replaced by 'upvotes' + ]]]; } public function getToStringExamples(): iterable