xmpp-parsers: Convert roster item to xso

This commit is contained in:
Emmanuel Gil Peyrot 2024-08-08 18:30:14 +02:00 committed by Jonas Schäfer
commit 2690e62060
2 changed files with 54 additions and 36 deletions

View file

@ -48,28 +48,30 @@ generate_attribute!(
) )
); );
generate_element!( /// Contact from the users contact list.
/// Contact from the users contact list. #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
Item, "item", ROSTER, #[xml(namespace = ns::ROSTER, name = "item")]
attributes: [ pub struct Item {
/// JID of this contact. /// JID of this contact.
jid: Required<BareJid> = "jid", #[xml(attribute)]
pub jid: BareJid,
/// Name of this contact. /// Name of this contact.
name: OptionEmpty<String> = "name", #[xml(attribute(default))]
pub name: Option<String>,
/// Subscription status of this contact. /// Subscription status of this contact.
subscription: Default<Subscription> = "subscription", #[xml(attribute(default))]
pub subscription: Subscription,
/// Indicates “Pending Out” sub-states for this contact. /// Indicates “Pending Out” sub-states for this contact.
ask: Default<Ask> = "ask", #[xml(attribute(default))]
], pub ask: Ask,
children: [ /// Groups this contact is part of.
/// Groups this contact is part of. #[xml(child(n = ..))]
groups: Vec<Group> = ("group", ROSTER) => Group pub groups: Vec<Group>,
] }
);
/// The contact list of the user. /// The contact list of the user.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
@ -134,10 +136,6 @@ mod tests {
assert_eq!(roster.ver, Some(String::from("ver7"))); assert_eq!(roster.ver, Some(String::from("ver7")));
assert_eq!(roster.items.len(), 2); assert_eq!(roster.items.len(), 2);
let elem2: Element = "<query xmlns='jabber:iq:roster' ver='ver7'><item jid='nurse@example.com'/><item jid='romeo@example.net' name=''/></query>".parse().unwrap();
let roster2 = Roster::try_from(elem2).unwrap();
assert_eq!(roster.items, roster2.items);
let elem: Element = "<query xmlns='jabber:iq:roster' ver='ver9'/>" let elem: Element = "<query xmlns='jabber:iq:roster' ver='ver9'/>"
.parse() .parse()
.unwrap(); .unwrap();
@ -300,17 +298,19 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string, FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(), _ => panic!(),
}; };
assert_eq!(message, "Required attribute 'jid' missing."); assert_eq!(
message,
"Required attribute field 'jid' on Item element missing."
);
/* let elem: Element = "<query xmlns='jabber:iq:roster'><item jid=''/></query>"
let elem: Element = "<query xmlns='jabber:iq:roster'><item jid=''/></query>".parse().unwrap(); .parse()
.unwrap();
let error = Roster::try_from(elem).unwrap_err(); let error = Roster::try_from(elem).unwrap_err();
let error = match error { assert_eq!(
Error::JidParseError(error) => error, format!("{error}"),
_ => panic!(), "text parse error: no domain found in this JID"
}; );
assert_eq!(error.description(), "Invalid JID, I guess?");
*/
let elem: Element = let elem: Element =
"<query xmlns='jabber:iq:roster'><item jid='coucou'><coucou/></item></query>" "<query xmlns='jabber:iq:roster'><item jid='coucou'><coucou/></item></query>"
@ -321,6 +321,6 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string, FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(), _ => panic!(),
}; };
assert_eq!(message, "Unknown child in item element."); assert_eq!(message, "Unknown child in Item element.");
} }
} }

View file

@ -195,6 +195,24 @@ macro_rules! generate_attribute {
$elem::None $elem::None
} }
} }
impl ::xso::FromXmlText for $elem {
fn from_xml_text(s: String) -> Result<$elem, xso::error::Error> {
s.parse().map_err(xso::error::Error::text_parse_error)
}
}
impl ::xso::AsXmlText for $elem {
fn as_xml_text(&self) -> Result<::std::borrow::Cow<'_, str>, xso::error::Error> {
Ok(::std::borrow::Cow::Borrowed($value))
}
#[allow(unreachable_patterns)]
fn as_optional_xml_text(&self) -> Result<Option<std::borrow::Cow<'_, str>>, xso::error::Error> {
Ok(Some(std::borrow::Cow::Borrowed(match self {
$elem::$symbol => $value,
$elem::None => return Ok(None),
})))
}
}
); );
($(#[$meta:meta])* $elem:ident, $name:tt, bool) => ( ($(#[$meta:meta])* $elem:ident, $name:tt, bool) => (
$(#[$meta])* $(#[$meta])*