use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::{Rc, Weak};
type NewWithChildren<'a> = (&'a str, HashMap<String, &'a str>, Vec<Rc<Element<'a>>>);
#[derive(Debug, Clone)]
pub struct Element<'a> {
pub ele_type: &'a str,
pub attributes: RefCell<HashMap<String, &'a str>>,
pub parent: RefCell<Weak<Element<'a>>>,
pub children: RefCell<Vec<Rc<Element<'a>>>>,
}
impl<'a> Element<'a> {
pub fn new((ele_type, attributes): (&'a str, HashMap<String, &'a str>)) -> Rc<Self> {
Rc::new(Element {
ele_type,
parent: RefCell::new(Weak::new()),
attributes: RefCell::new(attributes),
children: RefCell::new(vec![]),
})
}
pub fn new_width_children((ele_type, attributes, children): NewWithChildren<'a>) -> Rc<Self> {
let parent = Rc::new(Element {
ele_type,
attributes: RefCell::new(attributes),
parent: RefCell::new(Weak::new()),
children: RefCell::new(vec![]),
});
*parent.children.borrow_mut() = children
.iter()
.map(|node| {
let node = node.clone();
*node.parent.borrow_mut() = Rc::downgrade(&parent);
node
})
.collect();
parent
}
pub fn add_child(self: &Rc<Element<'a>>, new_item: Rc<Element<'a>>) {
let node = new_item.clone();
*node.parent.borrow_mut() = Rc::downgrade(self);
self.children.borrow_mut().push(new_item);
}
pub fn add_children(self: &Rc<Element<'a>>, new_items: Vec<Rc<Element<'a>>>) {
let mut new_items = new_items
.iter()
.map(|node| {
let node = node.clone();
*node.parent.borrow_mut() = Rc::downgrade(self);
node
})
.collect();
(self.children.borrow_mut()).append(&mut new_items);
}
}