Provide field context to Deserializer implementations
Also reorders deserialize() arguments.
This commit is contained in:
parent
7a2e6ac735
commit
c983e10a88
|
@ -67,8 +67,9 @@ fn deserialize_scalar_enum(
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), ::instant_xml::Error> {
|
||||
use ::instant_xml::Error;
|
||||
|
||||
|
@ -104,6 +105,7 @@ fn deserialize_forward_enum(
|
|||
}
|
||||
|
||||
let ident = &input.ident;
|
||||
let field_str = format!("{ident}::0");
|
||||
let mut matches = TokenStream::new();
|
||||
let mut variants = TokenStream::new();
|
||||
let mut borrowed = BTreeSet::new();
|
||||
|
@ -145,7 +147,7 @@ fn deserialize_forward_enum(
|
|||
variants.extend(
|
||||
quote!(if <#no_lifetime_type as FromXml>::matches(id, None) {
|
||||
let mut value = None;
|
||||
<#no_lifetime_type as FromXml>::deserialize(deserializer, &mut value)?;
|
||||
<#no_lifetime_type as FromXml>::deserialize(&mut value, #field_str, deserializer)?;
|
||||
*into = value.map(#ident::#v_ident);
|
||||
}),
|
||||
);
|
||||
|
@ -163,8 +165,9 @@ fn deserialize_forward_enum(
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), ::instant_xml::Error> {
|
||||
use ::instant_xml::de::Node;
|
||||
use ::instant_xml::{Accumulate, Error, FromXml};
|
||||
|
@ -284,8 +287,9 @@ fn deserialize_struct(
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), ::instant_xml::Error> {
|
||||
use ::instant_xml::de::Node;
|
||||
use ::instant_xml::{Accumulate, Error, FromXml, Id, Kind};
|
||||
|
@ -418,6 +422,7 @@ fn named_field(
|
|||
})
|
||||
.transpose()?;
|
||||
|
||||
let field_str = format!("{type_name}::{field_name}");
|
||||
if !field_meta.attribute {
|
||||
if let Some(with) = deserialize_with {
|
||||
if field_meta.direct {
|
||||
|
@ -430,14 +435,14 @@ fn named_field(
|
|||
tokens.r#match.extend(quote!(
|
||||
__Elements::#enum_name => {
|
||||
let mut nested = deserializer.nested(data);
|
||||
#with(&mut nested, &mut #enum_name)?;
|
||||
#with(&mut #enum_name, #field_str, &mut nested)?;
|
||||
},
|
||||
));
|
||||
} else if field_meta.direct {
|
||||
direct.extend(quote!(
|
||||
Node::Text(text) => {
|
||||
let mut nested = deserializer.for_node(Node::Text(text));
|
||||
<#no_lifetime_type>::deserialize(&mut nested, &mut #enum_name)?;
|
||||
<#no_lifetime_type>::deserialize(&mut #enum_name, #field_str, &mut nested)?;
|
||||
}
|
||||
));
|
||||
} else {
|
||||
|
@ -445,11 +450,11 @@ fn named_field(
|
|||
__Elements::#enum_name => match <#no_lifetime_type as FromXml>::KIND {
|
||||
Kind::Element => {
|
||||
let mut nested = deserializer.nested(data);
|
||||
<#no_lifetime_type>::deserialize(&mut nested, &mut #enum_name)?;
|
||||
<#no_lifetime_type>::deserialize(&mut #enum_name, #field_str, &mut nested)?;
|
||||
}
|
||||
Kind::Scalar => {
|
||||
let mut nested = deserializer.nested(data);
|
||||
<#no_lifetime_type>::deserialize(&mut nested, &mut #enum_name)?;
|
||||
<#no_lifetime_type>::deserialize(&mut #enum_name, #field_str, &mut nested)?;
|
||||
nested.ignore()?;
|
||||
}
|
||||
},
|
||||
|
@ -467,20 +472,19 @@ fn named_field(
|
|||
tokens.r#match.extend(quote!(
|
||||
__Attributes::#enum_name => {
|
||||
let mut nested = deserializer.nested(data);
|
||||
#with(&mut nested, &mut #enum_name)?;
|
||||
#with(&mut #enum_name, #field_str, &mut nested)?;
|
||||
},
|
||||
));
|
||||
} else {
|
||||
tokens.r#match.extend(quote!(
|
||||
__Attributes::#enum_name => {
|
||||
let mut nested = deserializer.for_node(Node::AttributeValue(attr.value));
|
||||
let new = <#no_lifetime_type as FromXml>::deserialize(&mut nested, &mut #enum_name)?;
|
||||
let new = <#no_lifetime_type as FromXml>::deserialize(&mut #enum_name, #field_str, &mut nested)?;
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let field_str = format!("{type_name}::{field_name}");
|
||||
return_val.extend(quote!(
|
||||
#field_name: #enum_name.try_done(#field_str)?,
|
||||
));
|
||||
|
@ -539,8 +543,9 @@ fn deserialize_tuple_struct(
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), ::instant_xml::Error> {
|
||||
use ::instant_xml::de::Node;
|
||||
use ::instant_xml::{Accumulate, Error, FromXml, Id, Kind};
|
||||
|
@ -578,7 +583,7 @@ fn unnamed_field(
|
|||
Some(Ok(Node::Open(data))) => {
|
||||
let mut nested = deserializer.nested(data);
|
||||
let mut value = <#no_lifetime_type as FromXml>::Accumulator::default();
|
||||
<#no_lifetime_type as FromXml>::deserialize(&mut nested, &mut value)?;
|
||||
<#no_lifetime_type as FromXml>::deserialize(&mut value, #field_str, &mut nested)?;
|
||||
nested.ignore()?;
|
||||
value
|
||||
}
|
||||
|
@ -588,13 +593,12 @@ fn unnamed_field(
|
|||
}
|
||||
Kind::Scalar => {
|
||||
let mut value = <#no_lifetime_type as FromXml>::Accumulator::default();
|
||||
<#no_lifetime_type as FromXml>::deserialize(deserializer, &mut value)?;
|
||||
<#no_lifetime_type as FromXml>::deserialize(&mut value, #field_str, deserializer)?;
|
||||
value
|
||||
}
|
||||
};
|
||||
));
|
||||
|
||||
let field_str = format!("{type_name}::{index}");
|
||||
return_val.extend(quote!(
|
||||
#name.try_done(#field_str)?,
|
||||
));
|
||||
|
@ -617,8 +621,9 @@ fn deserialize_unit_struct(input: &syn::DeriveInput, meta: &ContainerMeta) -> To
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), ::instant_xml::Error> {
|
||||
deserializer.ignore()?;
|
||||
*into = Some(Self);
|
||||
|
|
|
@ -333,8 +333,9 @@ impl<'xml> Iterator for Context<'xml> {
|
|||
}
|
||||
|
||||
pub fn borrow_cow_str<'xml>(
|
||||
deserializer: &mut Deserializer<'_, 'xml>,
|
||||
into: &mut Option<Cow<'xml, str>>,
|
||||
_: &'static str,
|
||||
deserializer: &mut Deserializer<'_, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
|
@ -349,8 +350,9 @@ pub fn borrow_cow_str<'xml>(
|
|||
}
|
||||
|
||||
pub fn borrow_cow_slice_u8<'xml>(
|
||||
deserializer: &mut Deserializer<'_, 'xml>,
|
||||
into: &mut Option<Cow<'xml, [u8]>>,
|
||||
_: &'static str,
|
||||
deserializer: &mut Deserializer<'_, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
|
|
|
@ -48,8 +48,9 @@ impl<'xml, T: FromStr> FromXml<'xml> for FromXmlStr<T> {
|
|||
}
|
||||
|
||||
fn deserialize(
|
||||
deserializer: &mut Deserializer<'_, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'_, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
|
@ -66,7 +67,7 @@ impl<'xml, T: FromStr> FromXml<'xml> for FromXmlStr<T> {
|
|||
Ok(())
|
||||
}
|
||||
Err(_) => Err(Error::UnexpectedValue(format!(
|
||||
"unable to parse {} from `{value}`",
|
||||
"unable to parse {} from `{value}` for {field}",
|
||||
type_name::<T>()
|
||||
))),
|
||||
}
|
||||
|
@ -86,8 +87,9 @@ impl<'xml> FromXml<'xml> for bool {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
|
@ -103,7 +105,7 @@ impl<'xml> FromXml<'xml> for bool {
|
|||
"false" | "0" => false,
|
||||
val => {
|
||||
return Err(Error::UnexpectedValue(format!(
|
||||
"unable to parse bool from '{val}'"
|
||||
"unable to parse bool from '{val}' for {field}"
|
||||
)))
|
||||
}
|
||||
};
|
||||
|
@ -181,15 +183,16 @@ macro_rules! from_xml_for_number {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
}
|
||||
|
||||
let mut value = None;
|
||||
FromXmlStr::<Self>::deserialize(deserializer, &mut value)?;
|
||||
FromXmlStr::<Self>::deserialize(&mut value, field, deserializer)?;
|
||||
if let Some(value) = value {
|
||||
*into = Some(value.0);
|
||||
}
|
||||
|
@ -226,15 +229,16 @@ impl<'xml> FromXml<'xml> for char {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
}
|
||||
|
||||
let mut value = None;
|
||||
FromXmlStr::<Self>::deserialize(deserializer, &mut value)?;
|
||||
FromXmlStr::<Self>::deserialize(&mut value, field, deserializer)?;
|
||||
if let Some(value) = value {
|
||||
*into = Some(value.0);
|
||||
}
|
||||
|
@ -256,8 +260,9 @@ impl<'xml> FromXml<'xml> for String {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
_: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
|
@ -285,8 +290,9 @@ impl<'xml> FromXml<'xml> for &'xml str {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
|
@ -301,7 +307,7 @@ impl<'xml> FromXml<'xml> for &'xml str {
|
|||
Cow::Borrowed(str) => *into = Some(str),
|
||||
Cow::Owned(_) => {
|
||||
return Err(Error::UnexpectedValue(format!(
|
||||
"string with escape characters cannot be deserialized as &str: '{value}'",
|
||||
"string with escape characters cannot be deserialized as &str for {field}: '{value}'",
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -327,16 +333,17 @@ where
|
|||
}
|
||||
|
||||
fn deserialize(
|
||||
deserializer: &mut Deserializer<'_, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'_, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
}
|
||||
|
||||
let mut value = <T::Owned as FromXml<'xml>>::Accumulator::default();
|
||||
T::Owned::deserialize(deserializer, &mut value)?;
|
||||
*into = Some(Cow::Owned(value.try_done("Cow<T>")?));
|
||||
T::Owned::deserialize(&mut value, field, deserializer)?;
|
||||
*into = Some(Cow::Owned(value.try_done(field)?));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -351,10 +358,11 @@ impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Option<T> {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
<T>::deserialize(deserializer, &mut into.value)?;
|
||||
<T>::deserialize(&mut into.value, field, deserializer)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -567,12 +575,13 @@ impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Vec<T> {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
let mut value = T::Accumulator::default();
|
||||
T::deserialize(deserializer, &mut value)?;
|
||||
into.push(value.try_done("Vec<T>")?);
|
||||
T::deserialize(&mut value, field, deserializer)?;
|
||||
into.push(value.try_done(field)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -640,8 +649,9 @@ impl<'xml> FromXml<'xml> for DateTime<Utc> {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
_: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
|
@ -701,8 +711,9 @@ impl<'xml> FromXml<'xml> for NaiveDate {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
_: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
|
@ -736,8 +747,9 @@ impl<'xml> FromXml<'xml> for () {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
_: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
_: &'static str,
|
||||
_: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
*into = Some(());
|
||||
Ok(())
|
||||
|
@ -767,15 +779,16 @@ impl<'xml> FromXml<'xml> for IpAddr {
|
|||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue);
|
||||
}
|
||||
|
||||
let mut value = None;
|
||||
FromXmlStr::<Self>::deserialize(deserializer, &mut value)?;
|
||||
FromXmlStr::<Self>::deserialize(&mut value, field, deserializer)?;
|
||||
if let Some(value) = value {
|
||||
*into = Some(value.0);
|
||||
}
|
||||
|
|
|
@ -40,8 +40,9 @@ pub trait FromXml<'xml>: Sized {
|
|||
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool;
|
||||
|
||||
fn deserialize<'cx>(
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
type Accumulator: Accumulate<Self>;
|
||||
|
@ -86,8 +87,12 @@ pub fn from_str<'xml, T: FromXml<'xml>>(input: &'xml str) -> Result<T, Error> {
|
|||
}
|
||||
|
||||
let mut value = T::Accumulator::default();
|
||||
T::deserialize(&mut Deserializer::new(root, &mut context), &mut value)?;
|
||||
value.try_done("root element")
|
||||
T::deserialize(
|
||||
&mut value,
|
||||
"<root element>",
|
||||
&mut Deserializer::new(root, &mut context),
|
||||
)?;
|
||||
value.try_done("<root element>")
|
||||
}
|
||||
|
||||
pub fn to_string(value: &(impl ToXml + ?Sized)) -> Result<String, Error> {
|
||||
|
|
|
@ -31,7 +31,7 @@ fn escape_back() {
|
|||
from_str(
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string><>&"'adsad"</string><str>str&</str></StructSpecialEntities>"
|
||||
),
|
||||
Err::<StructSpecialEntities, _>(Error::UnexpectedValue("string with escape characters cannot be deserialized as &str: 'str&'".to_owned()))
|
||||
Err::<StructSpecialEntities, _>(Error::UnexpectedValue("string with escape characters cannot be deserialized as &str for StructSpecialEntities::str: 'str&'".to_owned()))
|
||||
);
|
||||
|
||||
// Borrowed
|
||||
|
|
Loading…
Reference in New Issue