convert.rs

  1//! A module which exports a few traits for converting types to elements and attributes.
  2
  3use element::{Element, ElementBuilder};
  4
  5/// A struct which is used for emitting `Element`s and text nodes into an `Element` without
  6/// exposing more functionality than necessary.
  7pub struct ElementEmitter<'a>(&'a mut Element);
  8
  9impl<'a> ElementEmitter<'a> {
 10    /// Creates a new `ElementEmitter`.
 11    pub fn new(root: &'a mut Element) -> ElementEmitter<'a> {
 12        ElementEmitter(root)
 13    }
 14
 15    /// Appends an `Element` to the target.
 16    pub fn append_child(&mut self, element: Element) {
 17        self.0.append_child(element);
 18    }
 19
 20    /// Appends a text node to the target.
 21    pub fn append_text_node(&mut self, text: String) {
 22        self.0.append_text_node(text);
 23    }
 24}
 25
 26/// A trait for types which can be converted to one or multiple `Element`s.
 27pub trait IntoElements {
 28    /// Emits this as a sequence of text nodes and `Element`s.
 29    fn into_elements(self, emitter: &mut ElementEmitter);
 30}
 31
 32impl<T: IntoElements> IntoElements for Vec<T> {
 33    fn into_elements(self, emitter: &mut ElementEmitter) {
 34        for elem in self {
 35            elem.into_elements(emitter);
 36        }
 37    }
 38}
 39
 40impl<'a, T: IntoElements + Clone> IntoElements for &'a [T] {
 41    fn into_elements(self, emitter: &mut ElementEmitter) {
 42        self.to_vec().into_elements(emitter);
 43    }
 44}
 45
 46impl<T: IntoElements> IntoElements for Option<T> {
 47    fn into_elements(self, emitter: &mut ElementEmitter) {
 48        match self {
 49            Some(e) => e.into_elements(emitter),
 50            None => (),
 51        }
 52    }
 53}
 54
 55impl IntoElements for Element {
 56    fn into_elements(self, emitter: &mut ElementEmitter) {
 57        emitter.append_child(self);
 58    }
 59}
 60
 61impl IntoElements for ElementBuilder {
 62    fn into_elements(self, emitter: &mut ElementEmitter) {
 63        emitter.append_child(self.build());
 64    }
 65}
 66
 67impl IntoElements for String {
 68    fn into_elements(self, emitter: &mut ElementEmitter) {
 69        emitter.append_text_node(self);
 70    }
 71}
 72
 73impl<'a> IntoElements for &'a str {
 74    fn into_elements(self, emitter: &mut ElementEmitter) {
 75        emitter.append_text_node(self.to_owned());
 76    }
 77}
 78
 79/// A trait for types which can be converted to an attribute value.
 80pub trait IntoAttributeValue {
 81    /// Turns this into an attribute string, or None if it shouldn't be added.
 82    fn into_attribute_value(self) -> Option<String>;
 83}
 84
 85impl IntoAttributeValue for String {
 86    fn into_attribute_value(self) -> Option<String> {
 87        Some(self.clone())
 88    }
 89}
 90
 91impl<'a> IntoAttributeValue for &'a str {
 92    fn into_attribute_value(self) -> Option<String> {
 93        Some((*self).to_owned())
 94    }
 95}
 96
 97impl<T: IntoAttributeValue> IntoAttributeValue for Option<T> {
 98    fn into_attribute_value(self) -> Option<String> {
 99        self.and_then(|t| t.into_attribute_value())
100    }
101}