diff --git a/parsers/src/bookmarks2.rs b/parsers/src/bookmarks2.rs index 76db15a..93764ae 100644 --- a/parsers/src/bookmarks2.rs +++ b/parsers/src/bookmarks2.rs @@ -31,7 +31,7 @@ pub struct Conference { pub password: Option, /// Extensions elements. - pub extensions: Option>, + pub extensions: Vec, } impl Conference { @@ -53,18 +53,11 @@ impl TryFrom for Conference { name: get_attr!(root, "name", Option), nick: None, password: None, - extensions: None, + extensions: Vec::new(), }; for child in root.children().cloned() { - if child.is("extensions", ns::BOOKMARKS2) { - if conference.extensions.is_some() { - return Err(Error::ParseError( - "Conference must not have more than one extensions element.", - )); - } - conference.extensions = Some(child.children().cloned().collect()); - } else if child.is("nick", ns::BOOKMARKS2) { + if child.is("nick", ns::BOOKMARKS2) { if conference.nick.is_some() { return Err(Error::ParseError( "Conference must not have more than one nick.", @@ -82,6 +75,17 @@ impl TryFrom for Conference { check_no_children!(child, "password"); check_no_attributes!(child, "password"); conference.password = Some(child.text()); + } else if child.is("extensions", ns::BOOKMARKS2) { + if !conference.extensions.is_empty() { + return Err(Error::ParseError( + "Conference must not have more than one extensions element.", + )); + } + conference.extensions.extend(child.children().cloned()); + } else { + return Err(Error::ParseError( + "Unknown element in bookmarks2 conference", + )); } } @@ -105,8 +109,10 @@ impl From for Element { .map(|password| Element::builder("password", ns::BOOKMARKS2).append(password)), ) .append_all(match conference.extensions { - Some(extensions) => extensions, - None => vec![], + empty if empty.is_empty() => None, + extensions => { + Some(Element::builder("extensions", ns::BOOKMARKS2).append_all(extensions)) + } }) .build() } @@ -155,8 +161,8 @@ mod tests { assert_eq!(conference.name, Some(String::from("Test MUC"))); assert_eq!(conference.clone().nick.unwrap(), "Coucou"); assert_eq!(conference.clone().password.unwrap(), "secret"); - assert_eq!(conference.clone().extensions.unwrap().len(), 1); - assert!(conference.clone().extensions.unwrap()[0].is("test", "urn:xmpp:unknown")); + assert_eq!(conference.clone().extensions.len(), 1); + assert!(conference.clone().extensions[0].is("test", "urn:xmpp:unknown")); } #[test] diff --git a/parsers/src/lib.rs b/parsers/src/lib.rs index 0308740..8b85cd1 100644 --- a/parsers/src/lib.rs +++ b/parsers/src/lib.rs @@ -225,7 +225,7 @@ pub mod eme; /// XEP-0390: Entity Capabilities 2.0 pub mod ecaps2; -/// XEP-0402: Bookmarks 2 (This Time it's Serious) +/// XEP-0402: PEP Native Bookmarks pub mod bookmarks2; /// XEP-0421: Anonymous unique occupant identifiers for MUCs diff --git a/parsers/src/ns.rs b/parsers/src/ns.rs index 18a3ed5..00f8ce0 100644 --- a/parsers/src/ns.rs +++ b/parsers/src/ns.rs @@ -252,10 +252,12 @@ pub const ECAPS2: &str = "urn:xmpp:caps"; /// XEP-0390: Entity Capabilities 2.0 pub const ECAPS2_OPTIMIZE: &str = "urn:xmpp:caps:optimize"; -/// XEP-0402: Bookmarks 2 (This Time it's Serious) +/// XEP-0402: PEP Native Bookmarks pub const BOOKMARKS2: &str = "urn:xmpp:bookmarks:1"; -/// XEP-0402: Bookmarks 2 (This Time it's Serious) -pub const BOOKMARKS2_COMPAT: &str = "urn:xmpp:bookmarks:0#compat"; +/// XEP-0402: PEP Native Bookmarks +pub const BOOKMARKS2_COMPAT: &str = "urn:xmpp:bookmarks:1#compat"; +/// XEP-0402: PEP Native Bookmarks +pub const BOOKMARKS2_COMPAT_PEP: &str = "urn:xmpp:bookmarks:1#compat-pep"; /// XEP-0421: Anonymous unique occupant identifiers for MUCs pub const OID: &str = "urn:xmpp:occupant-id:0";