Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::collections::hash_map::HashMap;
- type TagChildren = Vec<Box<dyn Tag>>;
- macro_rules! hashmap {
- ($( $key: expr => $val: expr ),*) => {{
- let mut map = ::std::collections::HashMap::new();
- $( map.insert($key, $val); )*
- map
- }}
- }
- fn main() {
- let root = make_tag(
- "svg",
- vec![Box::new(make_tag(
- "rect",
- vec![],
- hashmap! {
- "width" => "50",
- "height" => "50",
- "fill" => "#FF00FF"
- },
- ))],
- hashmap! {"width" => "100", "height" => "100"},
- );
- println!("{}", root.render());
- }
- fn xml_escape(s: &String) -> String {
- s.replace("&", "&")
- .replace(">", ">")
- .replace("<", "<")
- }
- fn make_tag(name: &str, children: TagChildren, attributes: HashMap<&str, &str>) -> CommonTag {
- CommonTag {
- name: name.to_string(),
- children,
- attributes: attributes
- .iter()
- .map(|(&k, &v)| (k.to_string(), v.to_string()))
- .collect(),
- }
- }
- trait Tag {
- fn render(&self) -> String;
- }
- struct CommonTag {
- name: String,
- children: TagChildren,
- attributes: HashMap<String, String>,
- }
- impl Tag for CommonTag {
- fn render(&self) -> String {
- let mut result = String::new();
- result.push_str("<");
- result.push_str(&self.name);
- if self.attributes.len() > 0 {
- result.push(' ');
- for (key, value) in self.attributes.iter() {
- result.push_str(&key);
- result.push_str("=\"");
- result.push_str(&xml_escape(value));
- result.push_str("\" ")
- }
- }
- if self.children.len() > 0 {
- result.push('>');
- for child in self.children.iter() {
- result.push_str(&child.render())
- }
- result.push_str("</");
- result.push_str(&self.name);
- result.push_str(">")
- } else {
- result.push_str("/>")
- }
- result
- }
- }
- impl Tag for String {
- fn render(&self) -> String {
- xml_escape(self)
- }
- }
- struct Prerendered {
- content: String,
- }
- impl Tag for Prerendered {
- fn render(&self) -> String {
- self.content.clone()
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement