1 //! The nodes.
2 
3 use std::collections::hash_map::DefaultHasher;
4 use std::collections::HashMap;
5 use std::fmt;
6 
7 mod comment;
8 mod text;
9 mod value;
10 
11 pub use self::comment::Comment;
12 pub use self::text::Text;
13 pub use self::value::Value;
14 
15 /// Attributes.
16 pub type Attributes = HashMap<String, Value>;
17 
18 /// Child nodes.
19 pub type Children = Vec<Box<dyn Node>>;
20 
21 /// A node.
22 pub trait Node: 'static + fmt::Debug + fmt::Display + NodeClone + NodeDefaultHash {
23     /// Append a child node.
append<T>(&mut self, _: T) where Self: Sized, T: Node24     fn append<T>(&mut self, _: T)
25     where
26         Self: Sized,
27         T: Node;
28 
29     /// Assign an attribute.
assign<T, U>(&mut self, _: T, _: U) where Self: Sized, T: Into<String>, U: Into<Value>30     fn assign<T, U>(&mut self, _: T, _: U)
31     where
32         Self: Sized,
33         T: Into<String>,
34         U: Into<Value>;
35 }
36 
37 #[doc(hidden)]
38 pub trait NodeClone {
clone(&self) -> Box<dyn Node>39     fn clone(&self) -> Box<dyn Node>;
40 }
41 
42 #[doc(hidden)]
43 pub trait NodeDefaultHash {
default_hash(&self, state: &mut DefaultHasher)44     fn default_hash(&self, state: &mut DefaultHasher);
45 }
46 
47 impl<T> NodeClone for T
48 where
49     T: Node + Clone,
50 {
51     #[inline]
clone(&self) -> Box<dyn Node>52     fn clone(&self) -> Box<dyn Node> {
53         Box::new(Clone::clone(self))
54     }
55 }
56 
57 impl NodeDefaultHash for Box<dyn Node> {
58     #[inline]
default_hash(&self, state: &mut DefaultHasher)59     fn default_hash(&self, state: &mut DefaultHasher) {
60         NodeDefaultHash::default_hash(&**self, state)
61     }
62 }
63 
64 impl Clone for Box<dyn Node> {
65     #[inline]
clone(&self) -> Self66     fn clone(&self) -> Self {
67         NodeClone::clone(&**self)
68     }
69 }
70 
71 macro_rules! node(
72     ($struct_name:ident::$field_name:ident) => (
73         impl $struct_name {
74             /// Append a node.
75             pub fn add<T>(mut self, node: T) -> Self
76             where
77                 T: crate::node::Node,
78             {
79                 crate::node::Node::append(&mut self, node);
80                 self
81             }
82 
83             /// Assign an attribute.
84             #[inline]
85             pub fn set<T, U>(mut self, name: T, value: U) -> Self
86             where
87                 T: Into<String>,
88                 U: Into<crate::node::Value>,
89             {
90                 crate::node::Node::assign(&mut self, name, value);
91                 self
92             }
93 
94             /// Return the inner element.
95             #[inline]
96             pub fn get_inner(&self) -> &Element {
97                 &self.inner
98             }
99         }
100 
101         impl crate::node::Node for $struct_name {
102             #[inline]
103             fn append<T>(&mut self, node: T)
104             where
105                 T: crate::node::Node,
106             {
107                 self.$field_name.append(node);
108             }
109 
110             #[inline]
111             fn assign<T, U>(&mut self, name: T, value: U)
112             where
113                 T: Into<String>,
114                 U: Into<crate::node::Value>,
115             {
116                 self.$field_name.assign(name, value);
117             }
118         }
119 
120         impl ::std::fmt::Display for $struct_name {
121             #[inline]
122             fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
123                 self.$field_name.fmt(formatter)
124             }
125         }
126 
127         impl Into<Element> for $struct_name {
128             #[inline]
129             fn into(self) -> Element {
130                 self.inner
131             }
132         }
133     );
134 );
135 
136 pub mod element;
137