From 2690e62060ffb90f8e85ab622b7307aaaeda3a00 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Thu, 8 Aug 2024 18:30:14 +0200 Subject: [PATCH] xmpp-parsers: Convert roster item to xso --- parsers/src/roster.rs | 72 +++++++++++++++++++------------------- parsers/src/util/macros.rs | 18 ++++++++++ 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/parsers/src/roster.rs b/parsers/src/roster.rs index df9298657c0a5a7fcaa0564acdbb1efba51f1864..6722642305ae0ebff68d83564012a6f5a8c636fa 100644 --- a/parsers/src/roster.rs +++ b/parsers/src/roster.rs @@ -48,28 +48,30 @@ generate_attribute!( ) ); -generate_element!( - /// Contact from the user’s contact list. - Item, "item", ROSTER, - attributes: [ - /// JID of this contact. - jid: Required = "jid", - - /// Name of this contact. - name: OptionEmpty = "name", - - /// Subscription status of this contact. - subscription: Default = "subscription", - - /// Indicates “Pending Out” sub-states for this contact. - ask: Default = "ask", - ], - - children: [ - /// Groups this contact is part of. - groups: Vec = ("group", ROSTER) => Group - ] -); +/// Contact from the user’s contact list. +#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::ROSTER, name = "item")] +pub struct Item { + /// JID of this contact. + #[xml(attribute)] + pub jid: BareJid, + + /// Name of this contact. + #[xml(attribute(default))] + pub name: Option, + + /// Subscription status of this contact. + #[xml(attribute(default))] + pub subscription: Subscription, + + /// Indicates “Pending Out” sub-states for this contact. + #[xml(attribute(default))] + pub ask: Ask, + + /// Groups this contact is part of. + #[xml(child(n = ..))] + pub groups: Vec, +} /// The contact list of the user. #[derive(FromXml, AsXml, PartialEq, Debug, Clone)] @@ -134,10 +136,6 @@ mod tests { assert_eq!(roster.ver, Some(String::from("ver7"))); assert_eq!(roster.items.len(), 2); - let elem2: Element = "".parse().unwrap(); - let roster2 = Roster::try_from(elem2).unwrap(); - assert_eq!(roster.items, roster2.items); - let elem: Element = "" .parse() .unwrap(); @@ -300,17 +298,19 @@ mod tests { FromElementError::Invalid(Error::Other(string)) => string, _ => panic!(), }; - assert_eq!(message, "Required attribute 'jid' missing."); + assert_eq!( + message, + "Required attribute field 'jid' on Item element missing." + ); - /* - let elem: Element = "".parse().unwrap(); + let elem: Element = "" + .parse() + .unwrap(); let error = Roster::try_from(elem).unwrap_err(); - let error = match error { - Error::JidParseError(error) => error, - _ => panic!(), - }; - assert_eq!(error.description(), "Invalid JID, I guess?"); - */ + assert_eq!( + format!("{error}"), + "text parse error: no domain found in this JID" + ); let elem: Element = "" @@ -321,6 +321,6 @@ mod tests { FromElementError::Invalid(Error::Other(string)) => string, _ => panic!(), }; - assert_eq!(message, "Unknown child in item element."); + assert_eq!(message, "Unknown child in Item element."); } } diff --git a/parsers/src/util/macros.rs b/parsers/src/util/macros.rs index 24234c4312f3baff8cd939a4c31e5d96705ee500..9b38e8fee43923923d575dab6d51c809249d7eeb 100644 --- a/parsers/src/util/macros.rs +++ b/parsers/src/util/macros.rs @@ -195,6 +195,24 @@ macro_rules! generate_attribute { $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>, 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])*