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}