disco: Split Into<Element> for Identity and Feature.

Emmanuel Gil Peyrot created

Change summary

src/disco.rs | 63 ++++++++++++++++++++++++++++++++++-------------------
1 file changed, 40 insertions(+), 23 deletions(-)

Detailed changes

src/disco.rs 🔗

@@ -6,7 +6,7 @@
 
 use std::convert::TryFrom;
 
-use minidom::Element;
+use minidom::{Element, IntoElements, ElementEmitter};
 
 use error::Error;
 use ns;
@@ -18,6 +18,21 @@ pub struct Feature {
     pub var: String,
 }
 
+impl Into<Element> for Feature {
+    fn into(self) -> Element {
+        Element::builder("feature")
+                .ns(ns::DISCO_INFO)
+                .attr("var", self.var)
+                .build()
+    }
+}
+
+impl IntoElements for Feature {
+    fn into_elements(self, emitter: &mut ElementEmitter) {
+        emitter.append_child(self.into());
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct Identity {
     pub category: String, // TODO: use an enum here.
@@ -26,6 +41,24 @@ pub struct Identity {
     pub name: Option<String>,
 }
 
+impl Into<Element> for Identity {
+    fn into(self) -> Element {
+        Element::builder("identity")
+                .ns(ns::DISCO_INFO)
+                .attr("category", self.category)
+                .attr("type", self.type_)
+                .attr("xml:lang", self.xml_lang)
+                .attr("name", self.name)
+                .build()
+    }
+}
+
+impl IntoElements for Identity {
+    fn into_elements(self, emitter: &mut ElementEmitter) {
+        emitter.append_child(self.into());
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct Disco {
     pub node: Option<String>,
@@ -111,31 +144,15 @@ impl TryFrom<Element> for Disco {
 
 impl Into<Element> for Disco {
     fn into(self) -> Element {
-        let mut root = Element::builder("query")
-                               .ns(ns::DISCO_INFO)
-                               .attr("node", self.node.clone())
-                               .build();
-        for identity in self.identities {
-            let identity_element = Element::builder("identity")
-                                           .ns(ns::DISCO_INFO)
-                                           .attr("category", identity.category.clone())
-                                           .attr("type", identity.type_.clone())
-                                           .attr("xml:lang", identity.xml_lang.clone())
-                                           .attr("name", identity.name.clone())
-                                           .build();
-            root.append_child(identity_element);
-        }
-        for feature in self.features {
-            let feature_element = Element::builder("feature")
-                                          .ns(ns::DISCO_INFO)
-                                          .attr("var", feature.var.clone())
-                                          .build();
-            root.append_child(feature_element);
-        }
         for _ in self.extensions {
             panic!("Not yet implemented!");
         }
-        root
+        Element::builder("query")
+                .ns(ns::DISCO_INFO)
+                .attr("node", self.node)
+                .append(self.identities)
+                .append(self.features)
+                .build()
     }
 }