-
-
Notifications
You must be signed in to change notification settings - Fork 222
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
Error Deserializing Struct With flatten
-ed Tagged Enum
#278
Comments
I did a little more digging, using It looks like flattened structs generate a "field visitor" type that looks like this: impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(&self,
__formatter: &mut _serde::__private::Formatter)
-> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter,
"variant identifier")
}
fn visit_u64<__E>(self, __value: u64)
-> _serde::__private::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
0u64 => _serde::__private::Ok(__Field::__field0),
1u64 => _serde::__private::Ok(__Field::__field1),
_ =>
_serde::__private::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
&"variant index 0 <= i < 2")),
}
}
fn visit_str<__E>(self, __value: &str)
-> _serde::__private::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
"foo" => _serde::__private::Ok(__Field::__field0),
"bar" => _serde::__private::Ok(__Field::__field1),
_ => {
_serde::__private::Err(_serde::de::Error::unknown_variant(__value,
VARIANTS))
}
}
}
fn visit_bytes<__E>(self, __value: &[u8])
-> _serde::__private::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
b"foo" => _serde::__private::Ok(__Field::__field0),
b"bar" => _serde::__private::Ok(__Field::__field1),
_ => {
let __value = &_serde::__private::from_utf8_lossy(__value);
_serde::__private::Err(_serde::de::Error::unknown_variant(__value,
VARIANTS))
}
}
}
} Meaning it accepts map keys as:
In contrast, tagged enums use a "tag-content-other field visitor": impl<'de> Visitor<'de> for TagContentOtherFieldVisitor {
type Value = TagContentOtherField;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"{:?}, {:?}, or other ignored fields",
self.tag, self.content
)
}
fn visit_str<E>(self, field: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
if field == self.tag {
Ok(TagContentOtherField::Tag)
} else if field == self.content {
Ok(TagContentOtherField::Content)
} else {
Ok(TagContentOtherField::Other)
}
}
} Note that the tagged enum field visitor only accepts Line 647 in 41c71ed
So, I'm not sure how this should be fixed. Should
Personally, the second option looks "cleaner" to me. Not sure what others think. |
I think I have much smaller example that might be related to this issue. |
This is fixed in serde 1.0.162 by serde-rs/serde#2377. |
Version
Tested on both
v1.1.6
andmaster
branch.Briefly describe the bug.
Deserializing a struct with a flattened tagged enum field does not seem to work.
Include a complete program demonstrating a problem.
Code:
(Playground link).
What is the observed behavior of the code above?
Fails to deserialize with
invalid type: byte array, expected "kind", "parameter", or other ignored fields
error:What is the expected or desired behavior of the code above?
To correctly deserialize records as they are done in the case of flattened structs (also included in code example).
The text was updated successfully, but these errors were encountered: