enum Closing { TAG, NONE }
impl Closing {
fn clone(&self) -> Closing {
match *self {
Closing::NONE => Closing::NONE,
Closing::TAG => Closing::TAG
}
}
}
enum Children {
Text(String),
Node(Node)
}
pub struct Node {
tag: String,
attributes: Option<Vec<String>>,
children: Option<Vec<Children>>,
closing_type: Closing
}
impl Node {
pub fn set_attribute(&mut self, name: &str, value: &str) {
match &mut self.attributes {
Some(attributes) => attributes.push(format!("{}=\"{}\"", name, value)),
None => {
let mut attributes: Vec<String> = Vec::new();
attributes.push(format!("{}=\"{}\"", name, value));
self.attributes = Some(attributes);
},
}
}
pub fn set_attribute_list(&mut self, attributes: Vec<(&str, &str)>) {
for ( name, value ) in attributes {
self.set_attribute(name, value);
}
}
pub fn inner_text(&mut self, value: &str) {
match &mut self.children {
Some(child) => child.push(Children::Text(value.to_string())),
None => {
let mut children: Vec<Children> = Vec::new();
children.push(Children::Text(value.to_string()));
self.children = Some(children);
}
}
}
pub fn append_child(&mut self, node: Node) { match &mut self.children {
Some(child) => child.push(Children::Node(node)),
None => {
let mut children: Vec<Children> = Vec::new();
children.push(Children::Node(node));
self.children = Some(children);
}
}
}
pub fn append_child_list(&mut self, children: Vec<Node>) {
for node in children {
self.append_child(node);
}
}
pub fn clone_node(&self) -> Node {
let cloned_attributes = match &self.attributes {
Some(attrs) => Some(attrs.iter().cloned().collect()),
None => None,
};
let cloned_children = match &self.children {
Some(children) => {
let mut cloned_children = Vec::new();
for child in children {
cloned_children.push(match child {
Children::Text(text) => Children::Text(text.clone()),
Children::Node(node) => Children::Node(node.clone_node()),
});
}
Some(cloned_children)
}
None => None,
};
Node {
tag: self.tag.clone(),
attributes: cloned_attributes,
children: cloned_children,
closing_type: self.closing_type.clone(),
}
}
pub fn render(&self) -> String {
let attributes = match &self.attributes {
Some(attrs) => format!(" {}", attrs.join(" ")),
None => String::new(),
};
let children = match &self.children {
Some(children) => {
let mut children_html = String::new();
for child in children {
match child {
Children::Text(text) => children_html.push_str(text),
Children::Node(node) => children_html.push_str(&node.render()),
}
}
children_html
},
None => String::new(),
};
match &self.closing_type {
Closing::TAG => format!("<{}{}>{}</{}>", self.tag, attributes, children, self.tag),
Closing::NONE => format!("<{}{}>", self.tag, attributes),
}
}
}
pub struct Document;
impl Document {
pub fn create_element(element_tag: &str) -> Node {
let closing_type:Closing = match element_tag {
"area" | "base" | "br" | "command" | "col" | "embed" | "hr" | "img" | "input" | "link" | "meta" | "param" | "source" => Closing::NONE,
_ => Closing::TAG
};
Node { tag: element_tag.to_string(), attributes: None, children: None, closing_type }
}
}