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}