diff --git a/parsers/src/util/macros.rs b/parsers/src/util/macros.rs index 9b38e8fe..3921948a 100644 --- a/parsers/src/util/macros.rs +++ b/parsers/src/util/macros.rs @@ -482,304 +482,6 @@ macro_rules! generate_elem_id { ); } -macro_rules! decl_attr { - (OptionEmpty, $type:ty) => ( - Option<$type> - ); - (Option, $type:ty) => ( - Option<$type> - ); - (Required, $type:ty) => ( - $type - ); - (RequiredNonEmpty, $type:ty) => ( - $type - ); - (Default, $type:ty) => ( - $type - ); -} - -macro_rules! start_decl { - (Vec, $type:ty) => ( - Vec<$type> - ); - (Option, $type:ty) => ( - Option<$type> - ); - (Required, $type:ty) => ( - $type - ); - (Present, $type:ty) => ( - bool - ); -} - -macro_rules! start_parse_elem { - ($temp:ident: Vec) => { - let mut $temp = Vec::new(); - }; - ($temp:ident: Option) => { - let mut $temp = None; - }; - ($temp:ident: Required) => { - let mut $temp = None; - }; - ($temp:ident: Present) => { - let mut $temp = false; - }; -} - -macro_rules! do_parse { - ($elem:ident, Element) => { - Ok($elem) - }; - ($elem:ident, String) => { - Ok($elem.text()) - }; - ($elem:ident, $constructor:ident) => { - $constructor::try_from($elem).map_err(xso::error::Error::from) - }; -} - -macro_rules! do_parse_elem { - ($temp:ident: Vec = $constructor:ident => $elem:ident, $name:tt, $parent_name:tt) => { - match do_parse!($elem, $constructor) { - Ok(v) => Ok($temp.push(v)), - Err(e) => Err(e), - } - }; - ($temp:ident: Option = $constructor:ident => $elem:ident, $name:tt, $parent_name:tt) => { - if $temp.is_some() { - Err(xso::error::Error::Other( - concat!( - "Element ", - $parent_name, - " must not have more than one ", - $name, - " child." - ) - .into(), - )) - } else { - match do_parse!($elem, $constructor) { - Ok(v) => { - $temp = Some(v); - Ok(()) - } - Err(e) => Err(e), - } - } - }; - ($temp:ident: Required = $constructor:ident => $elem:ident, $name:tt, $parent_name:tt) => { - if $temp.is_some() { - Err(xso::error::Error::Other( - concat!( - "Element ", - $parent_name, - " must not have more than one ", - $name, - " child." - ) - .into(), - )) - } else { - match do_parse!($elem, $constructor) { - Ok(v) => { - $temp = Some(v); - Ok(()) - } - Err(e) => Err(e), - } - } - }; - ($temp:ident: Present = $constructor:ident => $elem:ident, $name:tt, $parent_name:tt) => { - if $temp { - Err(xso::error::Error::Other( - concat!( - "Element ", - $parent_name, - " must not have more than one ", - $name, - " child." - ) - .into(), - )) - } else { - $temp = true; - Ok(()) - } - }; -} - -macro_rules! finish_parse_elem { - ($temp:ident: Vec = $name:tt, $parent_name:tt) => { - $temp - }; - ($temp:ident: Option = $name:tt, $parent_name:tt) => { - $temp - }; - ($temp:ident: Required = $name:tt, $parent_name:tt) => { - $temp.ok_or(xso::error::Error::Other( - concat!("Missing child ", $name, " in ", $parent_name, " element.").into(), - ))? - }; - ($temp:ident: Present = $name:tt, $parent_name:tt) => { - $temp - }; -} - -macro_rules! generate_serialiser { - ($builder:ident, $parent:ident, $elem:ident, Required, String, ($name:tt, $ns:ident)) => { - $builder.append( - minidom::Element::builder($name, crate::ns::$ns) - .append(::minidom::Node::Text($parent.$elem)), - ) - }; - ($builder:ident, $parent:ident, $elem:ident, Option, String, ($name:tt, $ns:ident)) => { - $builder.append_all($parent.$elem.map(|elem| { - minidom::Element::builder($name, crate::ns::$ns).append(::minidom::Node::Text(elem)) - })) - }; - ($builder:ident, $parent:ident, $elem:ident, Option, $constructor:ident, ($name:tt, *)) => { - $builder.append_all( - $parent - .$elem - .map(|elem| ::minidom::Node::Element(minidom::Element::from(elem))), - ) - }; - ($builder:ident, $parent:ident, $elem:ident, Option, $constructor:ident, ($name:tt, $ns:ident)) => { - $builder.append_all( - $parent - .$elem - .map(|elem| ::minidom::Node::Element(minidom::Element::from(elem))), - ) - }; - ($builder:ident, $parent:ident, $elem:ident, Vec, $constructor:ident, ($name:tt, $ns:ident)) => { - $builder.append_all($parent.$elem.into_iter()) - }; - ($builder:ident, $parent:ident, $elem:ident, Present, $constructor:ident, ($name:tt, $ns:ident)) => { - $builder.append_all( - $parent - .$elem - .then(|| minidom::Element::builder($name, crate::ns::$ns)), - ) - }; - ($builder:ident, $parent:ident, $elem:ident, $_:ident, $constructor:ident, ($name:tt, $ns:ident)) => { - $builder.append(::minidom::Node::Element(minidom::Element::from( - $parent.$elem, - ))) - }; -} - -macro_rules! generate_child_test { - ($child:ident, $name:tt, *) => { - $child.is($name, ::minidom::NSChoice::Any) - }; - ($child:ident, $name:tt, $ns:tt) => { - $child.is($name, crate::ns::$ns) - }; -} - -macro_rules! generate_element { - ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:ident, attributes: [$($(#[$attr_meta:meta])* $attr:ident: $attr_action:tt<$attr_type:ty> = $attr_name:tt),+$(,)?]) => ( - generate_element!($(#[$meta])* $elem, $name, $ns, attributes: [$($(#[$attr_meta])* $attr: $attr_action<$attr_type> = $attr_name),*], children: []); - ); - ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:ident, children: [$($(#[$child_meta:meta])* $child_ident:ident: $coucou:tt<$child_type:ty> = ($child_name:tt, $child_ns:tt) => $child_constructor:ident),+$(,)?]) => ( - generate_element!($(#[$meta])* $elem, $name, $ns, attributes: [], children: [$($(#[$child_meta])* $child_ident: $coucou<$child_type> = ($child_name, $child_ns) => $child_constructor),*]); - ); - ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:ident, attributes: [$($(#[$attr_meta:meta])* $attr:ident: $attr_action:tt<$attr_type:ty> = $attr_name:tt),*$(,)?], children: [$($(#[$child_meta:meta])* $child_ident:ident: $coucou:tt<$child_type:ty> = ($child_name:tt, $child_ns:tt) => $child_constructor:ident),*$(,)?]) => ( - $(#[$meta])* - #[derive(Debug, Clone, PartialEq)] - pub struct $elem { - $( - $(#[$attr_meta])* - pub $attr: decl_attr!($attr_action, $attr_type), - )* - $( - $(#[$child_meta])* - pub $child_ident: start_decl!($coucou, $child_type), - )* - } - - impl ::xso::FromXml for $elem { - type Builder = ::xso::minidom_compat::FromEventsViaElement<$elem>; - - fn from_events( - qname: ::xso::exports::rxml::QName, - attrs: ::xso::exports::rxml::AttrMap, - ) -> Result { - if qname.0 != crate::ns::$ns || qname.1 != $name { - return Err(::xso::error::FromEventsError::Mismatch { - name: qname, - attrs, - }) - } - Self::Builder::new(qname, attrs) - } - } - - impl ::std::convert::TryFrom for $elem { - type Error = xso::error::FromElementError; - - fn try_from(mut elem: minidom::Element) -> Result<$elem, xso::error::FromElementError> { - check_self!(elem, $name, $ns); - check_no_unknown_attributes!(elem, $name, [$($attr_name),*]); - $( - start_parse_elem!($child_ident: $coucou); - )* - for _child in elem.take_contents_as_children() { - let residual = _child; - $( - // TODO: get rid of the explicit generate_child_test here - // once !295 has landed. - let residual = if generate_child_test!(residual, $child_name, $child_ns) { - match do_parse_elem!($child_ident: $coucou = $child_constructor => residual, $child_name, $name) { - Ok(()) => continue, - Err(other) => return Err(other.into()), - } - } else { - residual - }; - )* - let _ = residual; - return Err(xso::error::Error::Other(concat!("Unknown child in ", $name, " element.")).into()); - } - Ok($elem { - $( - $attr: get_attr!(elem, $attr_name, $attr_action), - )* - $( - $child_ident: finish_parse_elem!($child_ident: $coucou = $child_name, $name), - )* - }) - } - } - - impl From<$elem> for minidom::Element { - fn from(elem: $elem) -> minidom::Element { - let mut builder = minidom::Element::builder($name, crate::ns::$ns); - $( - builder = builder.attr($attr_name, elem.$attr); - )* - $( - builder = generate_serialiser!(builder, elem, $child_ident, $coucou, $child_constructor, ($child_name, $child_ns)); - )* - - builder.build() - } - } - - impl ::xso::AsXml for $elem { - type ItemIter<'x> = ::xso::minidom_compat::AsItemsViaElement<'x>; - - fn as_xml_iter(&self) -> Result, ::xso::error::Error> { - ::xso::minidom_compat::AsItemsViaElement::new(self.clone()) - } - } - ); -} - #[cfg(test)] macro_rules! assert_size ( ($t:ty, $sz:expr) => (