Simplify FromXml::KIND const

This commit is contained in:
Dirkjan Ochtman 2022-11-29 16:31:26 +01:00
parent 4eafa193bd
commit 0a323ba302
6 changed files with 45 additions and 73 deletions

View File

@ -84,7 +84,7 @@ fn deserialize_scalar_enum(
Ok(())
}
const KIND: ::instant_xml::Kind<'static> = ::instant_xml::Kind::Scalar;
const KIND: ::instant_xml::Kind = ::instant_xml::Kind::Scalar;
}
)
}
@ -142,7 +142,7 @@ fn deserialize_wrapped_enum(
}
let name = meta.tag();
let default_namespace = meta.default_namespace();
let default_ns = meta.default_namespace();
let generics = meta.xml_generics(borrowed);
let (xml_impl_generics, _, _) = generics.split_for_impl();
let (_, ty_generics, where_clause) = input.generics.split_for_impl();
@ -150,10 +150,7 @@ fn deserialize_wrapped_enum(
impl #xml_impl_generics FromXml<'xml> for #ident #ty_generics #where_clause {
#[inline]
fn matches(id: ::instant_xml::Id<'_>, field: Option<::instant_xml::Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
id == ::instant_xml::Id { name: #name, ns: #default_ns }
}
fn deserialize<'cx>(
@ -165,7 +162,7 @@ fn deserialize_wrapped_enum(
let node = match deserializer.next() {
Some(result) => result?,
None => return Err(Error::MissingValue(&<Self as FromXml>::KIND)),
None => return Err(Error::MissingValue(Self::KIND)),
};
let data = match node {
@ -185,10 +182,7 @@ fn deserialize_wrapped_enum(
Ok(())
}
const KIND: ::instant_xml::Kind<'static> = ::instant_xml::Kind::Element(::instant_xml::Id {
ns: #default_namespace,
name: #name,
});
const KIND: ::instant_xml::Kind = ::instant_xml::Kind::Element;
}
)
}
@ -336,10 +330,7 @@ fn deserialize_struct(
Ok(())
}
const KIND: ::instant_xml::Kind<'static> = ::instant_xml::Kind::Element(::instant_xml::Id {
ns: #default_namespace,
name: #name,
});
const KIND: ::instant_xml::Kind = ::instant_xml::Kind::Element;
}
)
}
@ -441,8 +432,8 @@ fn named_field(
));
} else {
tokens.r#match.extend(quote!(
__Elements::#enum_name => match <#no_lifetime_type as FromXml>::KIND {
Kind::Element(_) => {
__Elements::#enum_name => match <#no_lifetime_type>::KIND {
Kind::Element => {
let mut nested = deserializer.nested(data);
FromXml::deserialize(&mut nested, &mut #enum_name)?;
}
@ -552,10 +543,7 @@ fn deserialize_tuple_struct(
Ok(())
}
const KIND: ::instant_xml::Kind<'static> = ::instant_xml::Kind::Element(::instant_xml::Id {
ns: #default_namespace,
name: #name,
});
const KIND: ::instant_xml::Kind = ::instant_xml::Kind::Element;
}
)
}
@ -574,7 +562,7 @@ fn unnamed_field(
let name = Ident::new(&format!("v{index}"), Span::call_site());
declare_values.extend(quote!(
let #name = match <#no_lifetime_type as FromXml>::KIND {
Kind::Element(_) => match deserializer.next() {
Kind::Element => match deserializer.next() {
Some(Ok(Node::Open(data))) => {
let mut nested = deserializer.nested(data);
let mut value: Option<#no_lifetime_type> = None;
@ -584,7 +572,7 @@ fn unnamed_field(
}
Some(Ok(node)) => return Err(Error::UnexpectedNode(format!("{:?}", node))),
Some(Err(e)) => return Err(e),
None => return Err(Error::MissingValue(&<#no_lifetime_type as FromXml>::KIND)),
None => return Err(Error::MissingValue(<#no_lifetime_type as FromXml>::KIND)),
}
Kind::Scalar => {
let mut value: Option<#no_lifetime_type> = None;
@ -627,10 +615,7 @@ fn deserialize_unit_struct(input: &syn::DeriveInput, meta: &ContainerMeta) -> To
Ok(())
}
const KIND: ::instant_xml::Kind<'static> = ::instant_xml::Kind::Element(::instant_xml::Id {
ns: #default_namespace,
name: #name,
});
const KIND: ::instant_xml::Kind = ::instant_xml::Kind::Element;
}
)
}

View File

@ -36,7 +36,7 @@ impl<'cx, 'xml> Deserializer<'cx, 'xml> {
Some(Ok(Node::Text(s))) => Ok(s),
Some(Ok(node)) => Err(Error::ExpectedScalar(format!("{node:?}"))),
Some(Err(e)) => Err(e),
None => Err(Error::MissingValue(&Kind::Scalar)),
None => Err(Error::MissingValue(Kind::Scalar)),
}
}

View File

@ -38,7 +38,7 @@ impl<'xml, T: FromStr> FromXml<'xml> for FromXmlStr<T> {
}
}
const KIND: Kind<'static> = Kind::Scalar;
const KIND: Kind = Kind::Scalar;
}
impl<'xml> FromXml<'xml> for bool {
@ -65,11 +65,11 @@ impl<'xml> FromXml<'xml> for bool {
*into = Some(value.0);
Ok(())
}
None => Err(Error::MissingValue(&Kind::Scalar)),
None => Err(Error::MissingValue(Kind::Scalar)),
}
}
const KIND: Kind<'static> = Kind::Scalar;
const KIND: Kind = Kind::Scalar;
}
// Serializer
@ -142,11 +142,11 @@ macro_rules! from_xml_for_number {
*into = Some(value.0);
Ok(())
}
None => Err(Error::MissingValue(&Kind::Scalar)),
None => Err(Error::MissingValue(Kind::Scalar)),
}
}
const KIND: Kind<'static> = Kind::Scalar;
const KIND: Kind = Kind::Scalar;
}
};
}
@ -188,11 +188,11 @@ impl<'xml> FromXml<'xml> for char {
*into = Some(value.0);
Ok(())
}
None => Err(Error::MissingValue(&Kind::Scalar)),
None => Err(Error::MissingValue(Kind::Scalar)),
}
}
const KIND: Kind<'static> = Kind::Scalar;
const KIND: Kind = Kind::Scalar;
}
impl<'xml> FromXml<'xml> for String {
@ -217,7 +217,7 @@ impl<'xml> FromXml<'xml> for String {
Ok(())
}
const KIND: Kind<'static> = Kind::Scalar;
const KIND: Kind = Kind::Scalar;
}
impl<'xml> FromXml<'xml> for &'xml str {
@ -250,7 +250,7 @@ impl<'xml> FromXml<'xml> for &'xml str {
Ok(())
}
const KIND: Kind<'static> = Kind::Scalar;
const KIND: Kind = Kind::Scalar;
}
impl<'xml, 'a, T: ?Sized> FromXml<'xml> for Cow<'a, T>
@ -281,11 +281,11 @@ where
*into = Some(Cow::Owned(value));
Ok(())
}
None => Err(Error::MissingValue(&Kind::Scalar)),
None => Err(Error::MissingValue(Kind::Scalar)),
}
}
const KIND: Kind<'static> = Kind::Scalar;
const KIND: Kind = Kind::Scalar;
}
impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Option<T> {
@ -303,7 +303,7 @@ impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Option<T> {
<T>::deserialize(deserializer, value)?;
match value {
Some(_) => Ok(()),
None => Err(Error::MissingValue(&<T as FromXml<'_>>::KIND)),
None => Err(Error::MissingValue(<T as FromXml<'_>>::KIND)),
}
}
None => {
@ -314,7 +314,7 @@ impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Option<T> {
*into = Some(Some(value));
Ok(())
}
None => Err(Error::MissingValue(&<T as FromXml<'_>>::KIND)),
None => Err(Error::MissingValue(<T as FromXml<'_>>::KIND)),
}
}
}
@ -324,7 +324,7 @@ impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Option<T> {
Ok(None)
}
const KIND: Kind<'static> = <T>::KIND;
const KIND: Kind = <T>::KIND;
}
to_xml_for_number!(i8);
@ -514,7 +514,7 @@ impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Vec<T> {
Ok(Vec::new())
}
const KIND: Kind<'static> = T::KIND;
const KIND: Kind = T::KIND;
}
impl<T: ToXml> ToXml for Vec<T> {
@ -584,7 +584,7 @@ impl<'xml> FromXml<'xml> for DateTime<Utc> {
}
}
const KIND: Kind<'static> = Kind::Scalar;
const KIND: Kind = Kind::Scalar;
}
impl<'xml> FromXml<'xml> for () {
@ -604,7 +604,7 @@ impl<'xml> FromXml<'xml> for () {
Ok(())
}
const KIND: Kind<'static> = Kind::Scalar;
const KIND: Kind = Kind::Scalar;
}
impl ToXml for IpAddr {
@ -641,9 +641,9 @@ impl<'xml> FromXml<'xml> for IpAddr {
*into = Some(value.0);
Ok(())
}
None => Err(Error::MissingValue(&Kind::Scalar)),
None => Err(Error::MissingValue(Kind::Scalar)),
}
}
const KIND: Kind<'static> = Kind::Scalar;
const KIND: Kind = Kind::Scalar;
}

View File

@ -42,21 +42,17 @@ pub trait FromXml<'xml>: Sized {
// If the missing field is of type `Option<T>` then treat is as `None`,
// otherwise it is an error.
fn missing_value() -> Result<Self, Error> {
Err(Error::MissingValue(&Self::KIND))
Err(Error::MissingValue(Self::KIND))
}
const KIND: Kind<'static>;
const KIND: Kind;
}
pub fn from_str<'xml, T: FromXml<'xml>>(input: &'xml str) -> Result<T, Error> {
let (mut context, root) = Context::new(input)?;
let id = context.element_id(&root)?;
let expected = match T::KIND {
Kind::Scalar => return Err(Error::UnexpectedState("found scalar as root")),
Kind::Element(expected) => expected,
};
if id != expected {
if !T::matches(id, None) {
return Err(Error::UnexpectedValue("unexpected root"));
}
@ -102,7 +98,7 @@ pub enum Error {
#[error("missing tag")]
MissingTag,
#[error("missing value")]
MissingValue(&'static Kind<'static>),
MissingValue(Kind),
#[error("unexpected token: {0}")]
UnexpectedToken(String),
#[error("unknown prefix: {0}")]
@ -117,19 +113,10 @@ pub enum Error {
DuplicateValue,
}
#[derive(Debug, Eq, PartialEq)]
pub enum Kind<'a> {
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Kind {
Scalar,
Element(Id<'a>),
}
impl<'a> Kind<'a> {
pub const fn element(&self) -> Id<'a> {
match self {
Kind::Element(id) => *id,
_ => panic!("expected element kind"),
}
}
Element,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]

View File

@ -24,12 +24,12 @@ fn direct_namespaces() {
from_str(
"<StructDirectNamespace xmlns=\"URI\"><flag xmlns=\"WRONG\">true</flag></StructDirectNamespace>"
),
Err::<StructDirectNamespace, _>(Error::MissingValue(&Kind::Scalar))
Err::<StructDirectNamespace, _>(Error::MissingValue(Kind::Scalar))
);
// Wrong direct namespace - missing namespace
assert_eq!(
from_str("<StructDirectNamespace xmlns=\"URI\"><flag>true</flag></StructDirectNamespace>"),
Err::<StructDirectNamespace, _>(Error::MissingValue(&Kind::Scalar))
Err::<StructDirectNamespace, _>(Error::MissingValue(Kind::Scalar))
);
}

View File

@ -1,6 +1,6 @@
use similar_asserts::assert_eq;
use instant_xml::{from_str, Error, FromXml, Id, Kind};
use instant_xml::{from_str, Error, FromXml, Kind};
#[derive(Debug, Eq, PartialEq, FromXml)]
struct NestedWrongNamespace {
@ -72,7 +72,7 @@ fn default_namespaces() {
assert_eq!(
from_str("<StructWithWrongNestedNamespace xmlns=\"URI\" xmlns:dar=\"BAZ\"><NestedWrongNamespace><flag>true</flag></NestedWrongNamespace></StructWithWrongNestedNamespace>"),
Err::<StructWithWrongNestedNamespace, _>(
Error::MissingValue(&Kind::Element(Id { ns: "", name: "NestedWrongNamespace" }))
Error::MissingValue(Kind::Element)
)
);
}
@ -113,7 +113,7 @@ fn other_namespaces() {
from_str(
"<NestedOtherNamespace xmlns=\"URI\" xmlns:bar=\"WRONG\"><bar:flag>true</bar:flag></NestedOtherNamespace>"
),
Err::<NestedOtherNamespace, _>(Error::MissingValue(&Kind::Scalar))
Err::<NestedOtherNamespace, _>(Error::MissingValue(Kind::Scalar))
);
// Other namespace not-nested - missing parser prefix
@ -121,7 +121,7 @@ fn other_namespaces() {
from_str(
"<NestedOtherNamespace xmlns=\"URI\" xmlns:bar=\"BAR\"><flag>true</flag></NestedOtherNamespace>"
),
Err::<NestedOtherNamespace, _>(Error::MissingValue(&Kind::Scalar))
Err::<NestedOtherNamespace, _>(Error::MissingValue(Kind::Scalar))
);
// Correct child other namespace