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 try_from::TryFrom;
 8
 9use minidom::Element;
10
11use error::Error;
12
13use delay::Delay;
14use message::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>,
23}
24
25impl TryFrom<Element> for Forwarded {
26    type Err = Error;
27
28    fn try_from(elem: Element) -> Result<Forwarded, Error> {
29        if !elem.is("forwarded", ns::FORWARD) {
30            return Err(Error::ParseError("This is not a forwarded element."));
31        }
32        let mut delay = None;
33        let mut stanza = None;
34        for child in elem.children() {
35            if child.is("delay", ns::DELAY) {
36                delay = Some(Delay::try_from(child.clone())?);
37            } else if child.is("message", ns::DEFAULT_NS) {
38                stanza = Some(Message::try_from(child.clone())?);
39            // TODO: also handle the two other possibilities.
40            } else {
41                return Err(Error::ParseError("Unknown child in forwarded element."));
42            }
43        }
44        Ok(Forwarded {
45            delay: delay,
46            stanza: stanza,
47        })
48    }
49}
50
51impl From<Forwarded> for Element {
52    fn from(forwarded: Forwarded) -> Element {
53        Element::builder("forwarded")
54                .ns(ns::FORWARD)
55                .append(forwarded.delay.map(Element::from))
56                .append(forwarded.stanza.map(Element::from))
57                .build()
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn test_simple() {
67        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'/>".parse().unwrap();
68        Forwarded::try_from(elem).unwrap();
69    }
70
71    #[test]
72    fn test_invalid_child() {
73        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'><coucou/></forwarded>".parse().unwrap();
74        let error = Forwarded::try_from(elem).unwrap_err();
75        let message = match error {
76            Error::ParseError(string) => string,
77            _ => panic!(),
78        };
79        assert_eq!(message, "Unknown child in forwarded element.");
80    }
81
82    #[test]
83    fn test_serialise() {
84        let elem: Element = "<forwarded xmlns='urn:xmpp:forward:0'/>".parse().unwrap();
85        let forwarded = Forwarded { delay: None, stanza: None };
86        let elem2 = forwarded.into();
87        assert_eq!(elem, elem2);
88    }
89}