Crell / Serde

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

Deserializing top-level sequence #52

Open balthild opened 9 months ago

balthild commented 9 months ago

Detailed description

I wonder that how to deserialize top-level sequences into an object. I found that something similar already exists in this library, but limited to CSV.

For example, I have such a PHP array

$data = [
  ['id' => 1],
  ['id' => 2],
];

And the DTOs

readonly class MyList {
  public array $items;
}

readonly class MyItem {
  public int $id;
}

It seems that I cannot deserialize $data into an instance of MyList. I tried adding these attributes to MyList#items

#[Field(flatten: true)]
#[SequenceField(arrayType: MyItem::class)]

It deserializes the array without errors, but the type of items becomes associative array rather than MyItem. Seems like the SequenceField attribute is ignored if flatten: true.

Context

I am refactoring the API in an old project. Some of the routes accepts JSON arrays as its body, and I found that Serde does not provide a simple way to deserialize the arrays into strictly-typed objects.

Possible implementation

Generalize the feature existing in the CSV handler. The analogy in Rust's serde (transparent) could be a good API design for this feature.

Your environment

Crell commented 9 months ago

I think you just need to remove the Flatten directive?

I just ran a quick test using the PointList class, used in the CSV formatter tests. It worked fine with the standard formatters. What part of CSV-specific handling do you need?

Can you PR a failing test to better describe what you're trying to do? That would make it easier to determine what to do with it.

balthild commented 9 months ago

That's strange... I tried removing #[Field(flatten: true)] before and it didn't work. I tried in an MWE just now, and it still doesn't work.

The MWE: https://gist.github.com/balthild/37f72106f775e6b25417d4e778a38d5b