diff --git a/src/chatstates.rs b/src/chatstates.rs index e226f21d..6858c114 100644 --- a/src/chatstates.rs +++ b/src/chatstates.rs @@ -14,56 +14,26 @@ use error::Error; use ns; -/// Enum representing chatstate elements part of the -/// `http://jabber.org/protocol/chatstates` namespace. -#[derive(Debug, Clone)] -pub enum ChatState { - /// `` - Active, +generate_element_enum!( + /// Enum representing chatstate elements part of the + /// `http://jabber.org/protocol/chatstates` namespace. + ChatState, "chatstate", ns::CHATSTATES, { + /// `` + Active => "active", - /// `` - Composing, + /// `` + Composing => "composing", - /// `` - Gone, + /// `` + Gone => "gone", - /// `` - Inactive, + /// `` + Inactive => "inactive", - /// `` - Paused, -} - -impl TryFrom for ChatState { - type Err = Error; - - fn try_from(elem: Element) -> Result { - check_ns_only!(elem, "chatstate", ns::CHATSTATES); - check_no_children!(elem, "chatstate"); - check_no_attributes!(elem, "chatstate"); - Ok(match elem.name() { - "active" => ChatState::Active, - "composing" => ChatState::Composing, - "gone" => ChatState::Gone, - "inactive" => ChatState::Inactive, - "paused" => ChatState::Paused, - _ => return Err(Error::ParseError("This is not a chatstate element.")), - }) + /// `` + Paused => "paused", } -} - -impl From for Element { - fn from(chatstate: ChatState) -> Element { - Element::builder(match chatstate { - ChatState::Active => "active", - ChatState::Composing => "composing", - ChatState::Gone => "gone", - ChatState::Inactive => "inactive", - ChatState::Paused => "paused", - }).ns(ns::CHATSTATES) - .build() - } -} +); #[cfg(test)] mod tests { diff --git a/src/macros.rs b/src/macros.rs index b1d9374c..1569470a 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -96,6 +96,42 @@ macro_rules! generate_attribute { ); } +macro_rules! generate_element_enum { + ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:expr, {$($(#[$enum_meta:meta])* $enum:ident => $enum_name:tt),+,}) => ( + generate_element_enum!($(#[$meta])* $elem, $name, $ns, {$($(#[$enum_meta])* $enum => $enum_name),+}); + ); + ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:expr, {$($(#[$enum_meta:meta])* $enum:ident => $enum_name:tt),+}) => ( + $(#[$meta])* + #[derive(Debug, Clone, PartialEq)] + pub enum $elem { + $( + $(#[$enum_meta])* + $enum + ),+ + } + impl TryFrom for $elem { + type Err = Error; + fn try_from(elem: Element) -> Result<$elem, Error> { + check_ns_only!(elem, $name, $ns); + check_no_children!(elem, $name); + check_no_attributes!(elem, $name); + Ok(match elem.name() { + $($enum_name => $elem::$enum,)+ + _ => return Err(Error::ParseError(concat!("This is not a ", $name, " element."))), + }) + } + } + impl From<$elem> for Element { + fn from(elem: $elem) -> Element { + Element::builder(match elem { + $($elem::$enum => $enum_name,)+ + }).ns($ns) + .build() + } + } + ); +} + macro_rules! check_self { ($elem:ident, $name:tt, $ns:expr) => ( check_self!($elem, $name, $ns, $name);