data_forms, media_element: Implement forgotten serialisation.

Emmanuel Gil Peyrot created

Change summary

src/data_forms.rs    | 85 +++++++++++++++++++++++++++++++++++++++++++++
src/media_element.rs | 35 ++++++++++++++++++
2 files changed, 118 insertions(+), 2 deletions(-)

Detailed changes

src/data_forms.rs 🔗

@@ -7,7 +7,7 @@
 use std::convert::TryFrom;
 use std::str::FromStr;
 
-use minidom::Element;
+use minidom::{Element, IntoElements, IntoAttributeValue, ElementEmitter};
 
 use error::Error;
 use ns;
@@ -55,12 +55,48 @@ impl FromStr for FieldType {
     }
 }
 
+impl IntoAttributeValue for FieldType {
+    fn into_attribute_value(self) -> Option<String> {
+        Some(String::from(match self {
+            FieldType::Boolean => "boolean",
+            FieldType::Fixed => "fixed",
+            FieldType::Hidden => "hidden",
+            FieldType::JidMulti => "jid-multi",
+            FieldType::JidSingle => "jid-single",
+            FieldType::ListMulti => "list-multi",
+            FieldType::ListSingle => "list-single",
+            FieldType::TextMulti => "text-multi",
+            FieldType::TextPrivate => "text-private",
+            FieldType::TextSingle => "text-single",
+        }))
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct Option_ {
     pub label: Option<String>,
     pub value: String,
 }
 
+impl From<Option_> for Element {
+    fn from(option: Option_) -> Element {
+        Element::builder("option")
+                .ns(ns::DATA_FORMS)
+                .attr("label", option.label)
+                .append(Element::builder("value")
+                                .ns(ns::DATA_FORMS)
+                                .append(option.value)
+                                .build())
+                .build()
+    }
+}
+
+impl IntoElements for Option_ {
+    fn into_elements(self, emitter: &mut ElementEmitter) {
+        emitter.append_child(self.into());
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct Field {
     pub var: String,
@@ -72,6 +108,29 @@ pub struct Field {
     pub media: Vec<MediaElement>,
 }
 
+impl From<Field> for Element {
+    fn from(field: Field) -> Element {
+        Element::builder("field")
+                .ns(ns::DATA_FORMS)
+                .attr("var", field.var)
+                .attr("type", field.type_)
+                .attr("label", field.label)
+                .append(if field.required { Some(Element::builder("required").ns(ns::DATA_FORMS).build()) } else { None })
+                .append(field.options)
+                .append(field.values.iter().map(|value| {
+                     Element::builder("value").ns(ns::DATA_FORMS).append(value).build()
+                 }).collect::<Vec<_>>())
+                .append(field.media)
+                .build()
+    }
+}
+
+impl IntoElements for Field {
+    fn into_elements(self, emitter: &mut ElementEmitter) {
+        emitter.append_child(self.into());
+    }
+}
+
 #[derive(Debug, Clone, PartialEq)]
 pub enum DataFormType {
     Cancel,
@@ -95,6 +154,17 @@ impl FromStr for DataFormType {
     }
 }
 
+impl IntoAttributeValue for DataFormType {
+    fn into_attribute_value(self) -> Option<String> {
+        Some(String::from(match self {
+            DataFormType::Cancel => "cancel",
+            DataFormType::Form => "form",
+            DataFormType::Result_ => "result",
+            DataFormType::Submit => "submit",
+        }))
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct DataForm {
     pub type_: DataFormType,
@@ -226,6 +296,19 @@ impl TryFrom<Element> for DataForm {
     }
 }
 
+impl From<DataForm> for Element {
+    fn from(form: DataForm) -> Element {
+        Element::builder("x")
+                .ns(ns::DATA_FORMS)
+                .attr("type", form.type_)
+                .append(form.form_type)
+                .append(form.title)
+                .append(form.instructions)
+                .append(form.fields)
+                .build()
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;

src/media_element.rs 🔗

@@ -6,7 +6,7 @@
 
 use std::convert::TryFrom;
 
-use minidom::Element;
+use minidom::{Element, IntoElements, ElementEmitter};
 
 use error::Error;
 
@@ -18,6 +18,22 @@ pub struct URI {
     pub uri: String,
 }
 
+impl From<URI> for Element {
+    fn from(uri: URI) -> Element {
+        Element::builder("uri")
+                .ns(ns::MEDIA_ELEMENT)
+                .attr("type", uri.type_)
+                .append(uri.uri)
+                .build()
+    }
+}
+
+impl IntoElements for URI {
+    fn into_elements(self, emitter: &mut ElementEmitter) {
+        emitter.append_child(self.into());
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct MediaElement {
     pub width: Option<usize>,
@@ -54,6 +70,23 @@ impl TryFrom<Element> for MediaElement {
     }
 }
 
+impl From<MediaElement> for Element {
+    fn from(media: MediaElement) -> Element {
+        Element::builder("media")
+                .ns(ns::MEDIA_ELEMENT)
+                .attr("width", media.width)
+                .attr("height", media.height)
+                .append(media.uris)
+                .build()
+    }
+}
+
+impl IntoElements for MediaElement {
+    fn into_elements(self, emitter: &mut ElementEmitter) {
+        emitter.append_child(self.into());
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;