@@ -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::*;
@@ -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::*;