diff --git a/src/data_forms.rs b/src/data_forms.rs index 21d2ab1..4aba852 100644 --- a/src/data_forms.rs +++ b/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 { + 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, pub value: String, } +impl From 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, } +impl From 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::>()) + .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 { + 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 for DataForm { } } +impl From 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::*; diff --git a/src/media_element.rs b/src/media_element.rs index 931cab6..b1c36a6 100644 --- a/src/media_element.rs +++ b/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 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, @@ -54,6 +70,23 @@ impl TryFrom for MediaElement { } } +impl From 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::*;