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