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}