svg_simple_parser/ast.rs
1use std::cell::RefCell;
2use std::collections::HashMap;
3use std::rc::{Rc, Weak};
4
5type NewWithChildren<'a> = (&'a str, HashMap<String, &'a str>, Vec<Rc<Element<'a>>>);
6
7/// AST struct
8///
9/// `ele_type` the type of the element
10///
11/// `attributes` the attributes in the element
12///
13/// `children` the children in the element
14#[derive(Debug, Clone)]
15pub struct Element<'a> {
16 pub ele_type: &'a str,
17 pub attributes: RefCell<HashMap<String, &'a str>>,
18 pub parent: RefCell<Weak<Element<'a>>>,
19 pub children: RefCell<Vec<Rc<Element<'a>>>>,
20}
21
22impl<'a> Element<'a> {
23 /// new a element without children
24 /// ## Example
25 ///
26 /// ``` rust
27 /// use std::collections::HashMap;
28 /// use svg_simple_parser::Element;
29 ///
30 /// Element::new(("rect",HashMap::from([("width".to_owned(), "100"),("height".to_owned(), "100")])));
31 /// ```
32 ///
33 pub fn new((ele_type, attributes): (&'a str, HashMap<String, &'a str>)) -> Rc<Self> {
34 Rc::new(Element {
35 ele_type,
36 parent: RefCell::new(Weak::new()),
37 attributes: RefCell::new(attributes),
38 children: RefCell::new(vec![]),
39 })
40 }
41
42 /// new a element with children
43 /// ## Example
44 ///
45 /// ``` rust
46 /// use std::collections::HashMap;
47 /// use svg_simple_parser::Element;
48 ///
49 /// let child = Element::new(("rect",HashMap::from([("width".to_owned(), "100"),("height".to_owned(), "100")])));
50 /// Element::new_width_children(("rect",HashMap::from([("width".to_owned(), "100"),("height".to_owned(), "100")]),vec![child]));
51 /// ```
52 ///
53 pub fn new_width_children((ele_type, attributes, children): NewWithChildren<'a>) -> Rc<Self> {
54 let parent = Rc::new(Element {
55 ele_type,
56 attributes: RefCell::new(attributes),
57 parent: RefCell::new(Weak::new()),
58 children: RefCell::new(vec![]),
59 });
60 *parent.children.borrow_mut() = children
61 .iter()
62 .map(|node| {
63 let node = node.clone();
64 *node.parent.borrow_mut() = Rc::downgrade(&parent);
65 node
66 })
67 .collect();
68 parent
69 }
70
71 /// add a element to the children of the element.
72 ///
73 /// ## Example
74 ///
75 /// ``` rust
76 /// use std::collections::HashMap;
77 /// use svg_simple_parser::Element;
78 ///
79 /// let parent = Element::new(("rect",HashMap::from([("width".to_owned(), "100"),("height".to_owned(), "100")])));
80 /// let child = Element::new(("rect",HashMap::from([("width".to_owned(), "100"),("height".to_owned(), "100")])));
81 /// Element::add_child(parent.clone(),child.clone());
82 /// assert_eq!(parent.borrow().children.borrow().get(0),Some(&child));
83 /// ```
84 ///
85 pub fn add_child(self: &Rc<Element<'a>>, new_item: Rc<Element<'a>>) {
86 let node = new_item.clone();
87 *node.parent.borrow_mut() = Rc::downgrade(self);
88 self.children.borrow_mut().push(new_item);
89 }
90
91 /// add a list of element to the children of the element.
92 ///
93 /// ## Example
94 ///
95 /// ``` rust
96 /// use std::collections::HashMap;
97 /// use svg_simple_parser::Element;
98 ///
99 /// let parent = Element::new(("rect",HashMap::from([("width".to_owned(), "100"),("height".to_owned(), "100")])));
100 /// let child = Element::new(("rect",HashMap::from([("width".to_owned(), "100"),("height".to_owned(), "100")])));
101 /// Element::add_children(parent.clone(),vec![child.clone()].as_mut());
102 /// assert_eq!(parent.borrow().children.borrow().get(0),Some(&child));
103 /// ```
104 ///
105 pub fn add_children(self: &Rc<Element<'a>>, new_items: Vec<Rc<Element<'a>>>) {
106 let mut new_items = new_items
107 .iter()
108 .map(|node| {
109 let node = node.clone();
110 *node.parent.borrow_mut() = Rc::downgrade(self);
111 node
112 })
113 .collect();
114 (self.children.borrow_mut()).append(&mut new_items);
115 }
116}