mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-07-12 22:21:53 +00:00
disco: Use a macro for <identity/>.
This commit is contained in:
parent
c4d867571e
commit
b56582c8b5
2 changed files with 40 additions and 61 deletions
71
src/disco.rs
71
src/disco.rs
|
@ -43,21 +43,25 @@ impl Feature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Structure representing an `<identity xmlns='http://jabber.org/protocol/disco#info'/>` element.
|
generate_element!(
|
||||||
#[derive(Debug, Clone)]
|
/// Structure representing an `<identity xmlns='http://jabber.org/protocol/disco#info'/>` element.
|
||||||
pub struct Identity {
|
Identity, "identity", DISCO_INFO,
|
||||||
|
attributes: [
|
||||||
/// Category of this identity.
|
/// Category of this identity.
|
||||||
pub category: String, // TODO: use an enum here.
|
// TODO: use an enum here.
|
||||||
|
category: RequiredNonEmpty<String> = "category",
|
||||||
|
|
||||||
/// Type of this identity.
|
/// Type of this identity.
|
||||||
pub type_: String, // TODO: use an enum here.
|
// TODO: use an enum here.
|
||||||
|
type_: RequiredNonEmpty<String> = "type",
|
||||||
|
|
||||||
/// Lang of the name of this identity.
|
/// Lang of the name of this identity.
|
||||||
pub lang: Option<String>,
|
lang: Option<String> = "xml:lang",
|
||||||
|
|
||||||
/// Name of this identity.
|
/// Name of this identity.
|
||||||
pub name: Option<String>,
|
name: Option<String> = "name",
|
||||||
}
|
]
|
||||||
|
);
|
||||||
|
|
||||||
impl Identity {
|
impl Identity {
|
||||||
/// Create a new `<identity/>`.
|
/// Create a new `<identity/>`.
|
||||||
|
@ -89,53 +93,6 @@ impl Identity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<Element> for Identity {
|
|
||||||
type Err = Error;
|
|
||||||
|
|
||||||
fn try_from(elem: Element) -> Result<Identity, Error> {
|
|
||||||
check_self!(elem, "identity", DISCO_INFO, "disco#info identity");
|
|
||||||
check_no_children!(elem, "disco#info identity");
|
|
||||||
check_no_unknown_attributes!(
|
|
||||||
elem,
|
|
||||||
"disco#info identity",
|
|
||||||
["category", "type", "xml:lang", "name"]
|
|
||||||
);
|
|
||||||
|
|
||||||
let category = get_attr!(elem, "category", Required);
|
|
||||||
if category == "" {
|
|
||||||
return Err(Error::ParseError(
|
|
||||||
"Identity must have a non-empty 'category' attribute.",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let type_ = get_attr!(elem, "type", Required);
|
|
||||||
if type_ == "" {
|
|
||||||
return Err(Error::ParseError(
|
|
||||||
"Identity must have a non-empty 'type' attribute.",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Identity {
|
|
||||||
category,
|
|
||||||
type_,
|
|
||||||
lang: get_attr!(elem, "xml:lang", Option),
|
|
||||||
name: get_attr!(elem, "name", Option),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Identity> for Element {
|
|
||||||
fn from(identity: Identity) -> Element {
|
|
||||||
Element::builder("identity")
|
|
||||||
.ns(ns::DISCO_INFO)
|
|
||||||
.attr("category", identity.category)
|
|
||||||
.attr("type", identity.type_)
|
|
||||||
.attr("xml:lang", identity.lang)
|
|
||||||
.attr("name", identity.name)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Structure representing a `<query xmlns='http://jabber.org/protocol/disco#info'/>` element.
|
/// Structure representing a `<query xmlns='http://jabber.org/protocol/disco#info'/>` element.
|
||||||
///
|
///
|
||||||
/// It should only be used in an `<iq type='result'/>`, as it can only
|
/// It should only be used in an `<iq type='result'/>`, as it can only
|
||||||
|
@ -385,7 +342,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
message,
|
message,
|
||||||
"Identity must have a non-empty 'category' attribute."
|
"Required attribute 'category' must not be empty."
|
||||||
);
|
);
|
||||||
|
|
||||||
let elem: Element = "<query xmlns='http://jabber.org/protocol/disco#info'><identity category='coucou'/></query>".parse().unwrap();
|
let elem: Element = "<query xmlns='http://jabber.org/protocol/disco#info'><identity category='coucou'/></query>".parse().unwrap();
|
||||||
|
@ -402,7 +359,7 @@ mod tests {
|
||||||
Error::ParseError(string) => string,
|
Error::ParseError(string) => string,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
assert_eq!(message, "Identity must have a non-empty 'type' attribute.");
|
assert_eq!(message, "Required attribute 'type' must not be empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -33,6 +33,25 @@ macro_rules! get_attr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
($elem:ident, $attr:tt, RequiredNonEmpty, $value:ident, $func:expr) => {
|
||||||
|
match $elem.attr($attr) {
|
||||||
|
Some("") => {
|
||||||
|
return Err(crate::util::error::Error::ParseError(concat!(
|
||||||
|
"Required attribute '",
|
||||||
|
$attr,
|
||||||
|
"' must not be empty."
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
Some($value) => $func,
|
||||||
|
None => {
|
||||||
|
return Err(crate::util::error::Error::ParseError(concat!(
|
||||||
|
"Required attribute '",
|
||||||
|
$attr,
|
||||||
|
"' missing."
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
($elem:ident, $attr:tt, Default, $value:ident, $func:expr) => {
|
($elem:ident, $attr:tt, Default, $value:ident, $func:expr) => {
|
||||||
match $elem.attr($attr) {
|
match $elem.attr($attr) {
|
||||||
Some($value) => $func,
|
Some($value) => $func,
|
||||||
|
@ -408,6 +427,9 @@ macro_rules! decl_attr {
|
||||||
(Required, $type:ty) => (
|
(Required, $type:ty) => (
|
||||||
$type
|
$type
|
||||||
);
|
);
|
||||||
|
(RequiredNonEmpty, $type:ty) => (
|
||||||
|
$type
|
||||||
|
);
|
||||||
(Default, $type:ty) => (
|
(Default, $type:ty) => (
|
||||||
$type
|
$type
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue