version.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;
 8use minidom::Element;
 9use error::Error;
10use ns;
11
12#[derive(Debug, Clone)]
13pub struct Version {
14    pub name: String,
15    pub version: String,
16    pub os: Option<String>,
17}
18
19impl TryFrom<Element> for Version {
20    type Err = Error;
21
22    fn try_from(elem: Element) -> Result<Version, Error> {
23        check_self!(elem, "query", VERSION, "version");
24        check_no_attributes!(elem, "version");
25        let mut name = None;
26        let mut version = None;
27        let mut os = None;
28        for child in elem.children() {
29            if child.is("name", ns::VERSION) {
30                if name.is_some() {
31                    return Err(Error::ParseError("More than one name in version element."));
32                }
33                name = Some(child.text());
34            } else if child.is("version", ns::VERSION) {
35                if version.is_some() {
36                    return Err(Error::ParseError("More than one version in version element."));
37                }
38                version = Some(child.text());
39            } else if child.is("os", ns::VERSION) {
40                if os.is_some() {
41                    return Err(Error::ParseError("More than one os in version element."));
42                }
43                os = Some(child.text());
44            } else {
45                return Err(Error::ParseError("Unknown child in version element."));
46            }
47        }
48        let name = name.unwrap();
49        let version = version.unwrap();
50        Ok(Version {
51            name,
52            version,
53            os,
54        })
55    }
56}
57
58impl From<Version> for Element {
59    fn from(version: Version) -> Element {
60        Element::builder("query")
61                .ns(ns::VERSION)
62                .append(Element::builder("name")
63                                .ns(ns::VERSION)
64                                .append(version.name)
65                                .build())
66                .append(Element::builder("version")
67                                .ns(ns::VERSION)
68                                .append(version.version)
69                                .build())
70                .append(Element::builder("os")
71                                .ns(ns::VERSION)
72                                .append(version.os)
73                                .build())
74                .build()
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn test_simple() {
84        let elem: Element = "<query xmlns='jabber:iq:version'><name>xmpp-rs</name><version>0.3.0</version></query>".parse().unwrap();
85        let version = Version::try_from(elem).unwrap();
86        assert_eq!(version.name, String::from("xmpp-rs"));
87        assert_eq!(version.version, String::from("0.3.0"));
88        assert_eq!(version.os, None);
89    }
90}