diff --git a/src/attention.rs b/src/attention.rs index 7d0b1f2..da2e6f6 100644 --- a/src/attention.rs +++ b/src/attention.rs @@ -12,34 +12,7 @@ use error::Error; use ns; -/// Structure representing an `` element. -#[derive(Debug, Clone)] -pub struct Attention; - -impl TryFrom for Attention { - type Err = Error; - - fn try_from(elem: Element) -> Result { - if !elem.is("attention", ns::ATTENTION) { - return Err(Error::ParseError("This is not an attention element.")); - } - for _ in elem.children() { - return Err(Error::ParseError("Unknown child in attention element.")); - } - for _ in elem.attrs() { - return Err(Error::ParseError("Unknown attribute in attention element.")); - } - Ok(Attention) - } -} - -impl From for Element { - fn from(_: Attention) -> Element { - Element::builder("attention") - .ns(ns::ATTENTION) - .build() - } -} +generate_empty_element!(Attention, "attention", ns::ATTENTION); #[cfg(test)] mod tests { diff --git a/src/lib.rs b/src/lib.rs index 2184a84..9f3b80b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -159,6 +159,36 @@ macro_rules! check_no_unknown_attributes { ); } +macro_rules! generate_empty_element { + ($elem:ident, $name:tt, $ns:expr) => ( + // TODO: Find a better way to concatenate doc. + #[doc="Structure representing a "] + #[doc=$name] + #[doc=" element."] + #[derive(Debug, Clone)] + pub struct $elem; + + impl TryFrom for $elem { + type Err = Error; + + fn try_from(elem: Element) -> Result<$elem, Error> { + check_self!(elem, $name, $ns); + check_no_children!(elem, $name); + check_no_unknown_attributes!(elem, $name, []); + Ok($elem) + } + } + + impl From<$elem> for Element { + fn from(_: $elem) -> Element { + Element::builder("attention") + .ns($ns) + .build() + } + } + ); +} + macro_rules! generate_id { ($elem:ident) => ( #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/src/ping.rs b/src/ping.rs index c97fa50..d4044f4 100644 --- a/src/ping.rs +++ b/src/ping.rs @@ -13,34 +13,7 @@ use error::Error; use ns; -/// Structure representing a `` element. -#[derive(Debug, Clone)] -pub struct Ping; - -impl TryFrom for Ping { - type Err = Error; - - fn try_from(elem: Element) -> Result { - if !elem.is("ping", ns::PING) { - return Err(Error::ParseError("This is not a ping element.")); - } - for _ in elem.children() { - return Err(Error::ParseError("Unknown child in ping element.")); - } - for _ in elem.attrs() { - return Err(Error::ParseError("Unknown attribute in ping element.")); - } - Ok(Ping) - } -} - -impl From for Element { - fn from(_: Ping) -> Element { - Element::builder("ping") - .ns(ns::PING) - .build() - } -} +generate_empty_element!(Ping, "ping", ns::PING); #[cfg(test)] mod tests {