Advertisement
qevitta

Untitled

Jan 3rd, 2022
686
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.38 KB | None | 0 0
  1. use std::collections::hash_map::HashMap;
  2. type TagChildren = Vec<Box<dyn Tag>>;
  3.  
  4. macro_rules! hashmap {
  5.     ($( $key: expr => $val: expr ),*) => {{
  6.          let mut map = ::std::collections::HashMap::new();
  7.          $( map.insert($key, $val); )*
  8.          map
  9.     }}
  10. }
  11.  
  12. fn main() {
  13.     let root = make_tag(
  14.         "svg",
  15.         vec![Box::new(make_tag(
  16.             "rect",
  17.             vec![],
  18.             hashmap! {
  19.                 "width" => "50",
  20.                 "height" => "50",
  21.                 "fill" => "#FF00FF"
  22.             },
  23.         ))],
  24.         hashmap! {"width" => "100", "height" => "100"},
  25.     );
  26.     println!("{}", root.render());
  27. }
  28.  
  29. fn xml_escape(s: &String) -> String {
  30.     s.replace("&", "&amp;")
  31.         .replace(">", "&gt;")
  32.         .replace("<", "&lt;")
  33. }
  34.  
  35. fn make_tag(name: &str, children: TagChildren, attributes: HashMap<&str, &str>) -> CommonTag {
  36.     CommonTag {
  37.         name: name.to_string(),
  38.         children,
  39.         attributes: attributes
  40.             .iter()
  41.             .map(|(&k, &v)| (k.to_string(), v.to_string()))
  42.             .collect(),
  43.     }
  44. }
  45.  
  46. trait Tag {
  47.     fn render(&self) -> String;
  48. }
  49.  
  50. struct CommonTag {
  51.     name: String,
  52.     children: TagChildren,
  53.     attributes: HashMap<String, String>,
  54. }
  55.  
  56. impl Tag for CommonTag {
  57.     fn render(&self) -> String {
  58.         let mut result = String::new();
  59.  
  60.         result.push_str("<");
  61.         result.push_str(&self.name);
  62.  
  63.         if self.attributes.len() > 0 {
  64.             result.push(' ');
  65.             for (key, value) in self.attributes.iter() {
  66.                 result.push_str(&key);
  67.                 result.push_str("=\"");
  68.                 result.push_str(&xml_escape(value));
  69.                 result.push_str("\" ")
  70.             }
  71.         }
  72.  
  73.         if self.children.len() > 0 {
  74.             result.push('>');
  75.             for child in self.children.iter() {
  76.                 result.push_str(&child.render())
  77.             }
  78.             result.push_str("</");
  79.             result.push_str(&self.name);
  80.             result.push_str(">")
  81.         } else {
  82.             result.push_str("/>")
  83.         }
  84.  
  85.         result
  86.     }
  87. }
  88.  
  89. impl Tag for String {
  90.     fn render(&self) -> String {
  91.         xml_escape(self)
  92.     }
  93. }
  94.  
  95. struct Prerendered {
  96.     content: String,
  97. }
  98.  
  99. impl Tag for Prerendered {
  100.     fn render(&self) -> String {
  101.         self.content.clone()
  102.     }
  103. }
  104.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement