-
Notifications
You must be signed in to change notification settings - Fork 750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More permissive support for sequence -> struct deser #2432
Comments
Your use-case could be solved by using #[derive(Debug, Deserialize)]
struct A {
number: i32,
text: String,
#[serde(flatten)]
_extra: IgnoredAny,
} ...if not for several obstacles:
|
failures (6): regression::issue2432::deny_unknown_fields::seq regression::issue2432::deny_unknown_fields::tuple regression::issue2432::deny_unknown_fields::tuple_struct regression::issue2432::no_deny_unknown_fields::seq regression::issue2432::no_deny_unknown_fields::tuple regression::issue2432::no_deny_unknown_fields::tuple_struct
I think this use case would be a better fit for a helper library, as opposed to changing how permissive everybody's derived impls are. I've found usually the fact that some formats (e.g. serde_json, but not serde_yaml) allow deserializing serde structs from an array is already surprising for people, even with only matching lengths. I think accepting arbitrarily long sequences of other data would be worse / more often not what you want. Depending on your use case, an appropriate implementation might look something like: #[derive(Deserialize)]
#[serde(remote = "Self")]
struct A {
number: i32,
text: String,
}
impl<'de> Deserialize<'de> for A {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
ignore_tail(deserializer, Self::deserialize)
}
} or a derive macro which produces the above. And/or something you could use with |
Then maybe change |
Whether it is allowed is a property of the format just as much as the Deserialize impl. Both need to support it. You can write Deserialize impls that uniformly only deserialize from a map, even in data formats that would ordinarily support deserializing structs from an array (like serde_json). And you can write data formats that uniformly do not allow deserializing any struct from an array (serde_yaml does this). Regarding why derived Deserialize impls have that functionality and leave it up to the data format whether to use it: it's because formats like postcard, where field names do not exist, can only deserialize structs by feeding them a list of field data in order. If derived Deserialize impls did not support receiving a list of fields in order without field names, you could not deserialize them from postcard and other compact binary formats. |
Thanks for the suggestion. But I'm still not sure how I implement impl<'de> Deserialize<'de> for A {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
ignore_tail(deserializer, Self::deserialize)
}
} |
failures (6): regression::issue2432::deny_unknown_fields::seq regression::issue2432::deny_unknown_fields::tuple regression::issue2432::deny_unknown_fields::tuple_struct regression::issue2432::no_deny_unknown_fields::seq regression::issue2432::no_deny_unknown_fields::tuple regression::issue2432::no_deny_unknown_fields::tuple_struct
failures (6): regression::issue2432::deny_unknown_fields::seq regression::issue2432::deny_unknown_fields::tuple regression::issue2432::deny_unknown_fields::tuple_struct regression::issue2432::no_deny_unknown_fields::seq regression::issue2432::no_deny_unknown_fields::tuple regression::issue2432::no_deny_unknown_fields::tuple_struct
failures (6): regression::issue2432::deny_unknown_fields::seq regression::issue2432::deny_unknown_fields::tuple regression::issue2432::deny_unknown_fields::tuple_struct regression::issue2432::no_deny_unknown_fields::seq regression::issue2432::no_deny_unknown_fields::tuple regression::issue2432::no_deny_unknown_fields::tuple_struct
failures (6): regression::issue2432::deny_unknown_fields::seq regression::issue2432::deny_unknown_fields::tuple regression::issue2432::deny_unknown_fields::tuple_struct regression::issue2432::no_deny_unknown_fields::seq regression::issue2432::no_deny_unknown_fields::tuple regression::issue2432::no_deny_unknown_fields::tuple_struct
failures (6): regression::issue2432::deny_unknown_fields::seq regression::issue2432::deny_unknown_fields::tuple regression::issue2432::deny_unknown_fields::tuple_struct regression::issue2432::no_deny_unknown_fields::seq regression::issue2432::no_deny_unknown_fields::tuple regression::issue2432::no_deny_unknown_fields::tuple_struct
It is possible to deserialize sequence data into a struct. E.g.
However, the number of fields are required to match the sequence length. This has a couple of consequences:
Ideally I'd like a way of ignoring the tail.
And json sequences
[1234,"hello",[],345.234,true]
&[1234,"hello",[],345.234,true,123]
would work.Example: Implementing the trait for this behaviour is fairly verbose
Is there, or could there be, a way of achieving this without implementing
Deserialize for A
?The text was updated successfully, but these errors were encountered: