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 if let Some(e) = self {
49 e.into_elements(emitter);
50 }
51 }
52}
53
54impl IntoElements for Element {
55 fn into_elements(self, emitter: &mut ElementEmitter) {
56 emitter.append_child(self);
57 }
58}
59
60impl IntoElements for ElementBuilder {
61 fn into_elements(self, emitter: &mut ElementEmitter) {
62 emitter.append_child(self.build());
63 }
64}
65
66impl IntoElements for String {
67 fn into_elements(self, emitter: &mut ElementEmitter) {
68 emitter.append_text_node(self);
69 }
70}
71
72impl<'a> IntoElements for &'a String {
73 fn into_elements(self, emitter: &mut ElementEmitter) {
74 emitter.append_text_node(self.to_owned());
75 }
76}
77
78impl<'a> IntoElements for &'a str {
79 fn into_elements(self, emitter: &mut ElementEmitter) {
80 emitter.append_text_node(self.to_owned());
81 }
82}
83
84/// A trait for types which can be converted to an attribute value.
85pub trait IntoAttributeValue {
86 /// Turns this into an attribute string, or None if it shouldn't be added.
87 fn into_attribute_value(self) -> Option<String>;
88}
89
90impl IntoAttributeValue for String {
91 fn into_attribute_value(self) -> Option<String> {
92 Some(self)
93 }
94}
95
96impl<'a> IntoAttributeValue for &'a String {
97 fn into_attribute_value(self) -> Option<String> {
98 Some(self.to_owned())
99 }
100}
101
102impl<'a> IntoAttributeValue for &'a str {
103 fn into_attribute_value(self) -> Option<String> {
104 Some(self.to_owned())
105 }
106}
107
108impl<T: IntoAttributeValue> IntoAttributeValue for Option<T> {
109 fn into_attribute_value(self) -> Option<String> {
110 self.and_then(|t| t.into_attribute_value())
111 }
112}