Crell / Serde

Robust Serde (serialization/deserialization) library for PHP 8.
Other
299 stars 14 forks source link

Type check scalar arrays #12

Closed repli2dev closed 1 year ago

repli2dev commented 1 year ago

I would like to properly deserialize array of scalar values (int, strings)...

Detailed description

The same way as #[SequenceField(arrayType: ExampleDTO::class)] can be provided to ensure all items are of particular type the scalar types should work with #[SequenceField(arrayType: 'string')]

Context

This ensures that the deserialized object complies to the type declaration/documentation and can be relied on to some extend matching current PHP state-of-the-art as type-checked for example by PHPStan.

This helps everyone that aims to do strict input validation of incoming API payloads.

Possible implementation

When fiddling with this

// ArrayBasedDeformatter.php line 104 changed to
if (class_exists($class) || interface_exists($class) || in_array($class, $allowedScalar types])) {

make it work so it throws

Crell\Serde\TypeMismatch : Expected value of type string when writing to property 0, but found type int.

on invalid type

Your environment

Crell commented 1 year ago

Hm. Interesting. Though I question if using a string is the right way to specify the type. For array keys, I defined an enum. I don't think the same enum can be used here, since bool and array (array of arrays) are also technically allowed; though that then means arrayType becomes a union type. I'm not sure off hand if that breaks anything... 😄

Would you be open to giving that a shot and filing a PR for it that I could review?

repli2dev commented 1 year ago

I question if using a string is the right way to specify the type.

If you mean that there should be rather arrayType: ScalarTypes::STRING then yes I agree, this was just for the sake of clarify and also as a now somehow working example.

For array keys, I defined an enum. I don't think the same enum can be used here

No, KeyTypes are (to my knowledge) subset of ScalarTypes so I would split the enums for sure.

array (array of arrays) are also technically allowed; though that then means arrayType becomes a union type. I'm not sure off hand if that breaks anything

Yeah that could go wrong pretty simple, also with someone wanting using int|float...


So yes I will try to to a PR for a simple approach soon.