diff --git a/docs/2-features/01-mapper.md b/docs/2-features/01-mapper.md index 4dcad42d9..933ca3238 100644 --- a/docs/2-features/01-mapper.md +++ b/docs/2-features/01-mapper.md @@ -242,7 +242,7 @@ final readonly class AddressSerializer implements Serializer ::: -Of course, Tempest provides casters and serializers for the most common data types, including arrays, booleans, dates, enumerations, integers and value objects. +Of course, Tempest provides casters and serializers for the most common data types, including arrays, booleans, dates, enumerations, floats, integers and value objects. ### Registering casters and serializers globally diff --git a/packages/mapper/src/Serializer.php b/packages/mapper/src/Serializer.php index 1e18af8dd..8d03a63c7 100644 --- a/packages/mapper/src/Serializer.php +++ b/packages/mapper/src/Serializer.php @@ -7,7 +7,7 @@ interface Serializer { /** - * Serializes the given input into a string, array, or integer. + * Serializes the given input into an array, boolean, float, integer, or string. */ - public function serialize(mixed $input): array|string|int; + public function serialize(mixed $input): array|bool|float|int|string; } diff --git a/packages/mapper/src/Serializers/BooleanSerializer.php b/packages/mapper/src/Serializers/BooleanSerializer.php index 06611cc16..d892ce0bd 100644 --- a/packages/mapper/src/Serializers/BooleanSerializer.php +++ b/packages/mapper/src/Serializers/BooleanSerializer.php @@ -23,12 +23,12 @@ public static function accepts(PropertyReflector|TypeReflector $input): bool return in_array($type->getName(), ['bool', 'boolean'], strict: true); } - public function serialize(mixed $input): string + public function serialize(mixed $input): bool { if (! is_bool($input)) { throw new ValueCouldNotBeSerialized('boolean'); } - return $input ? 'true' : 'false'; + return $input; } } diff --git a/packages/mapper/src/Serializers/FloatSerializer.php b/packages/mapper/src/Serializers/FloatSerializer.php index bb547f90f..e09665ad4 100644 --- a/packages/mapper/src/Serializers/FloatSerializer.php +++ b/packages/mapper/src/Serializers/FloatSerializer.php @@ -23,12 +23,12 @@ public static function accepts(PropertyReflector|TypeReflector $input): bool return in_array($type->getName(), ['double', 'float'], strict: true); } - public function serialize(mixed $input): string + public function serialize(mixed $input): float { if (! is_float($input)) { throw new ValueCouldNotBeSerialized('float'); } - return (string) $input; + return $input; } } diff --git a/packages/mapper/src/Serializers/IntegerSerializer.php b/packages/mapper/src/Serializers/IntegerSerializer.php index ecac29641..e9e75e551 100644 --- a/packages/mapper/src/Serializers/IntegerSerializer.php +++ b/packages/mapper/src/Serializers/IntegerSerializer.php @@ -23,12 +23,12 @@ public static function accepts(PropertyReflector|TypeReflector $input): bool return in_array($type->getName(), ['int', 'integer'], strict: true); } - public function serialize(mixed $input): string + public function serialize(mixed $input): int { if (! is_int($input)) { throw new ValueCouldNotBeSerialized('integer'); } - return (string) $input; + return $input; } } diff --git a/tests/Integration/Mapper/Fixtures/ObjectWithScalarValues.php b/tests/Integration/Mapper/Fixtures/ObjectWithScalarValues.php new file mode 100644 index 000000000..2570d2ff4 --- /dev/null +++ b/tests/Integration/Mapper/Fixtures/ObjectWithScalarValues.php @@ -0,0 +1,17 @@ +assertSame( [ 'a' => 'a', - 'b' => '3.1416', + 'b' => 3.1416, 'c' => null, ], $array, ); } + + #[Test] + public function object_with_scalar_values_to_array(): void + { + $array = map(new ObjectWithScalarValues( + active: true, + score: 1.5, + count: 3, + ))->toArray(); + + $this->assertSame( + [ + 'active' => true, + 'score' => 1.5, + 'count' => 3, + ], + $array, + ); + } } diff --git a/tests/Integration/Mapper/Mappers/ObjectToJsonMapperTest.php b/tests/Integration/Mapper/Mappers/ObjectToJsonMapperTest.php index 4af0f13df..a570c3ca7 100644 --- a/tests/Integration/Mapper/Mappers/ObjectToJsonMapperTest.php +++ b/tests/Integration/Mapper/Mappers/ObjectToJsonMapperTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\Attributes\Test; use Tests\Tempest\Integration\FrameworkIntegrationTestCase; use Tests\Tempest\Integration\Mapper\Fixtures\ObjectA; +use Tests\Tempest\Integration\Mapper\Fixtures\ObjectWithScalarValues; use function Tempest\Mapper\map; @@ -22,4 +23,23 @@ public function object_to_json(): void $this->assertSame('{"a":"a","b":"b"}', $json); } + + #[Test] + public function object_with_scalar_values_to_json(): void + { + $json = map(new ObjectWithScalarValues( + active: true, + score: 1.5, + count: 3, + ))->toJson(); + + $this->assertSame( + [ + 'active' => true, + 'score' => 1.5, + 'count' => 3, + ], + json_decode($json, associative: true, flags: JSON_THROW_ON_ERROR), + ); + } } diff --git a/tests/Integration/Mapper/Serializers/ArrayOfObjectsSerializerTest.php b/tests/Integration/Mapper/Serializers/ArrayOfObjectsSerializerTest.php index 7c6f590a3..87d493347 100644 --- a/tests/Integration/Mapper/Serializers/ArrayOfObjectsSerializerTest.php +++ b/tests/Integration/Mapper/Serializers/ArrayOfObjectsSerializerTest.php @@ -19,11 +19,11 @@ public function serialize(): void [ 'stringProp' => 'a', 'stringableProp' => 'a', - 'intProp' => '1', + 'intProp' => 1, 'nullableIntProp' => null, - 'floatProp' => '0.1', + 'floatProp' => 0.1, 'nullableFloatProp' => null, - 'boolProp' => 'true', + 'boolProp' => true, 'nullableBoolProp' => null, 'arrayProp' => '["a"]', 'serializeWithProp' => 'aa', diff --git a/tests/Integration/Mapper/Serializers/BooleanSerializerTest.php b/tests/Integration/Mapper/Serializers/BooleanSerializerTest.php index 7b271c544..79fca8755 100644 --- a/tests/Integration/Mapper/Serializers/BooleanSerializerTest.php +++ b/tests/Integration/Mapper/Serializers/BooleanSerializerTest.php @@ -13,12 +13,12 @@ final class BooleanSerializerTest extends TestCase public function serialize(): void { $this->assertSame( - 'true', + true, new BooleanSerializer()->serialize(true), ); $this->assertSame( - 'false', + false, new BooleanSerializer()->serialize(false), ); } diff --git a/tests/Integration/Mapper/Serializers/FloatSerializerTest.php b/tests/Integration/Mapper/Serializers/FloatSerializerTest.php index 7ae90b08d..02f446bae 100644 --- a/tests/Integration/Mapper/Serializers/FloatSerializerTest.php +++ b/tests/Integration/Mapper/Serializers/FloatSerializerTest.php @@ -13,7 +13,7 @@ final class FloatSerializerTest extends TestCase public function serialize(): void { $this->assertSame( - '0.1', + 0.1, new FloatSerializer()->serialize(0.1), ); } diff --git a/tests/Integration/Mapper/Serializers/IntegerSerializerTest.php b/tests/Integration/Mapper/Serializers/IntegerSerializerTest.php index 593a7c825..b406cdb25 100644 --- a/tests/Integration/Mapper/Serializers/IntegerSerializerTest.php +++ b/tests/Integration/Mapper/Serializers/IntegerSerializerTest.php @@ -13,7 +13,7 @@ final class IntegerSerializerTest extends TestCase public function serialize(): void { $this->assertSame( - '1', + 1, new IntegerSerializer()->serialize(1), ); }