forwarding.rs

 1// Copyright (c) 2017 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
 2//
 3// This Source Code Form is subject to the terms of the Mozilla Public
 4// License, v. 2.0. If a copy of the MPL was not distributed with this
 5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
 6
 7use std::convert::TryFrom;
 8
 9use minidom::Element;
10
11use error::Error;
12
13use delay::Delay;
14use message;
15
16use ns;
17
18#[derive(Debug, Clone)]
19pub struct Forwarded {
20    pub delay: Option<Delay>,
21    // XXX: really?  Option?
22    pub stanza: Option<message::Message>,
23}
24
25pub fn parse_forwarded(root: &Element) -> Result<Forwarded, Error> {
26    if !root.is("forwarded", ns::FORWARD) {
27        return Err(Error::ParseError("This is not a forwarded element."));
28    }
29    let mut delay = None;
30    let mut stanza = None;
31    for child in root.children() {
32        if child.is("delay", ns::DELAY) {
33            delay = Some(Delay::try_from(child)?);
34        } else if child.is("message", ns::JABBER_CLIENT) {
35            stanza = Some(message::parse_message(child)?);
36        // TODO: also handle the five other possibilities.
37        } else {
38            return Err(Error::ParseError("Unknown child in forwarded element."));
39        }
40    }
41    Ok(Forwarded {
42        delay: delay,
43        stanza: stanza,
44    })
45}
46
47pub fn serialise(forwarded: &Forwarded) -> Element {
48    Element::builder("forwarded")
49            .ns(ns::FORWARD)
50            .append(match forwarded.delay { Some(ref delay) => { let elem: Element = delay.into(); Some(elem) }, None => None })
51            .append(forwarded.stanza.clone())
52            .build()
53}
54
55#[cfg(test)]
56mod tests {
57    use minidom::Element;
58    use error::Error;
59    use forwarding;
60
61    #[test]
62    fn test_simple() {
63        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'/>".parse().unwrap();
64        forwarding::parse_forwarded(&elem).unwrap();
65    }
66
67    #[test]
68    fn test_invalid_child() {
69        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'><coucou/></forwarded>".parse().unwrap();
70        let error = forwarding::parse_forwarded(&elem).unwrap_err();
71        let message = match error {
72            Error::ParseError(string) => string,
73            _ => panic!(),
74        };
75        assert_eq!(message, "Unknown child in forwarded element.");
76    }
77
78    #[test]
79    fn test_serialise() {
80        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'/>".parse().unwrap();
81        let forwarded = forwarding::Forwarded { delay: None, stanza: None };
82        let elem2 = forwarding::serialise(&forwarded);
83        assert_eq!(elem, elem2);
84    }
85}