chatstates: Generate ChatState automatically.

This commit is contained in:
Emmanuel Gil Peyrot 2017-11-24 04:27:35 +00:00
parent cec581baa0
commit 2661259e9a
2 changed files with 51 additions and 45 deletions

View file

@ -14,56 +14,26 @@ use error::Error;
use ns; use ns;
/// Enum representing chatstate elements part of the generate_element_enum!(
/// `http://jabber.org/protocol/chatstates` namespace. /// Enum representing chatstate elements part of the
#[derive(Debug, Clone)] /// `http://jabber.org/protocol/chatstates` namespace.
pub enum ChatState { ChatState, "chatstate", ns::CHATSTATES, {
/// `<active xmlns='http://jabber.org/protocol/chatstates'/>` /// `<active xmlns='http://jabber.org/protocol/chatstates'/>`
Active, Active => "active",
/// `<composing xmlns='http://jabber.org/protocol/chatstates'/>` /// `<composing xmlns='http://jabber.org/protocol/chatstates'/>`
Composing, Composing => "composing",
/// `<gone xmlns='http://jabber.org/protocol/chatstates'/>` /// `<gone xmlns='http://jabber.org/protocol/chatstates'/>`
Gone, Gone => "gone",
/// `<inactive xmlns='http://jabber.org/protocol/chatstates'/>` /// `<inactive xmlns='http://jabber.org/protocol/chatstates'/>`
Inactive, Inactive => "inactive",
/// `<paused xmlns='http://jabber.org/protocol/chatstates'/>` /// `<paused xmlns='http://jabber.org/protocol/chatstates'/>`
Paused, Paused => "paused",
}
impl TryFrom<Element> for ChatState {
type Err = Error;
fn try_from(elem: Element) -> Result<ChatState, Error> {
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.")),
})
} }
} );
impl From<ChatState> 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)] #[cfg(test)]
mod tests { mod tests {

View file

@ -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<Element> 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 { macro_rules! check_self {
($elem:ident, $name:tt, $ns:expr) => ( ($elem:ident, $name:tt, $ns:expr) => (
check_self!($elem, $name, $ns, $name); check_self!($elem, $name, $ns, $name);