From cc3773aca1373903c8c626f780079ddeb8e72f02 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Wed, 28 Oct 2020 14:41:34 +0100 Subject: [PATCH] Set subscribe element optional and add corresponding parsing --- xmpp-parsers/src/pubsub/pubsub.rs | 61 ++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/xmpp-parsers/src/pubsub/pubsub.rs b/xmpp-parsers/src/pubsub/pubsub.rs index a21f36af..1811a8d4 100644 --- a/xmpp-parsers/src/pubsub/pubsub.rs +++ b/xmpp-parsers/src/pubsub/pubsub.rs @@ -297,7 +297,7 @@ pub enum PubSub { /// A subcribe request. Subscribe { /// The subscribe request. - subscribe: Subscribe, + subscribe: Option, /// The options related to this subscribe request. options: Option, @@ -358,6 +358,37 @@ impl TryFrom for PubSub { create, configure: None, }); + } else if child.is("subscribe", ns::PUBSUB) { + if payload.is_some() { + return Err(Error::ParseError( + "Payload is already defined in pubsub element.", + )); + } + let subscribe = Subscribe::try_from(child.clone())?; + payload = Some(PubSub::Subscribe { + subscribe: Some(subscribe), + options: None, + }); + } else if child.is("options", ns::PUBSUB) { + if let Some(PubSub::Subscribe { subscribe, options }) = payload { + if options.is_some() { + return Err(Error::ParseError( + "Options is already defined in pubsub element.", + )); + } + let options = Some(Options::try_from(child.clone())?); + payload = Some(PubSub::Subscribe { subscribe, options }); + } else if payload.is_none() { + let options = Options::try_from(child.clone())?; + payload = Some(PubSub::Subscribe { + subscribe: None, + options: Some(options), + }); + } else { + return Err(Error::ParseError( + "Payload is already defined in pubsub element.", + )); + } } else if child.is("configure", ns::PUBSUB) { if let Some(PubSub::Create { create, configure }) = payload { if configure.is_some() { @@ -479,6 +510,16 @@ impl From for Element { } elems } + PubSub::Subscribe { subscribe, options } => { + let mut elems = vec![]; + if let Some(subscribe) = subscribe { + elems.push(Element::from(subscribe)); + } + if let Some(options) = options { + elems.push(Element::from(options)); + } + elems + } PubSub::Publish { publish, publish_options, @@ -495,7 +536,6 @@ impl From for Element { PubSub::Retract(retract) => vec![Element::from(retract)], PubSub::Subscription(subscription) => vec![Element::from(subscription)], PubSub::Subscriptions(subscriptions) => vec![Element::from(subscriptions)], - PubSub::Subscribe(subscribe) => vec![Element::from(subscribe)], PubSub::Unsubscribe(unsubscribe) => vec![Element::from(unsubscribe)], }) .build() @@ -678,6 +718,23 @@ mod tests { assert_eq!(subscribe_options2.required, true); } + #[test] + fn test_options_without_subscribe() { + let elem: Element = "".parse().unwrap(); + let elem1 = elem.clone(); + let pubsub = PubSub::try_from(elem).unwrap(); + match pubsub.clone() { + PubSub::Subscribe { subscribe, options } => { + assert!(subscribe.is_none()); + assert!(options.is_some()); + } + _ => panic!(), + } + + let elem2 = Element::from(pubsub); + assert_eq!(elem1, elem2); + } + #[test] fn test_serialize_options() { let reference: Element = ""