elvis_shared/tree/
node.rs1use std::cell::RefCell;
2use std::rc::{Rc, Weak};
3use std::{
4 collections::{hash_map::DefaultHasher, HashMap},
5 hash::Hasher,
6};
7
8fn hash(tag: &str, s: &[u8]) -> String {
9 let mut hasher = DefaultHasher::new();
10 hasher.write(s);
11
12 let res = format!("{:x}", hasher.finish());
13 format!("{}-{}", &tag, &res[(res.len() - 6)..])
14}
15
16#[derive(Clone, Debug, Default)]
18pub struct Node {
19 pub attrs: HashMap<String, String>,
21 pub children: Vec<Rc<RefCell<Node>>>,
23 pub tag: String,
25 pub pre: Option<Weak<RefCell<Node>>>,
27}
28
29impl Node {
30 pub fn drain(t: Rc<RefCell<Node>>) {
32 if let Some(pre) = &t.borrow().pre {
33 let u = pre.upgrade().expect("drain child failed");
34 u.borrow_mut().remove(t.clone());
35 u.borrow_mut().update();
36 }
37 }
38
39 pub fn idx(&mut self, path: &mut Vec<u8>) {
41 let h = hash(&self.tag, &path);
42 self.attrs.entry("id".into()).or_insert(h);
43
44 path.push(0);
45 for t in self.children.iter() {
46 t.borrow_mut().idx(path);
47 if let Some(last) = path.last_mut() {
48 *last += 1;
49 }
50 }
51 }
52
53 pub fn locate(&self, mut path: Vec<usize>) -> Vec<usize> {
55 if let Some(pre) = &self.pre {
56 let u = pre.upgrade().expect("locate widget failed");
57 for (i, t) in u.borrow().children.iter().enumerate() {
58 if t.borrow().eq(self) {
59 path.push(i);
60 return u.borrow().locate(path);
61 }
62 }
63 }
64
65 path
66 }
67
68 pub fn new(
70 attrs: HashMap<String, String>,
71 children: Vec<Rc<RefCell<Node>>>,
72 pre: Option<Weak<RefCell<Node>>>,
73 tag: String,
74 ) -> Rc<RefCell<Node>> {
75 let t = Node {
76 attrs,
77 children,
78 pre,
79 tag,
80 };
81
82 Rc::new(RefCell::new(t))
83 }
84
85 pub fn push(r: Rc<RefCell<Node>>, c: Rc<RefCell<Node>>) {
87 let pre = Rc::downgrade(&r);
88 c.borrow_mut().pre = Some(pre.clone());
89
90 pre.upgrade()
91 .expect("push child to tree failed")
92 .borrow_mut()
93 .children
94 .push(c);
95
96 r.borrow_mut().update();
97 }
98
99 pub fn remove(&mut self, c: Rc<RefCell<Node>>) {
101 self.children.retain(|x| x != &c);
102 self.update();
103 }
104
105 pub fn replace(&mut self, mut t: Node) {
107 t.pre = self.pre.clone();
108 std::mem::swap(self, &mut t);
109
110 t.update();
111 }
112
113 pub fn update(&mut self) {}
115}
116
117impl PartialEq for Node {
118 fn eq(&self, other: &Self) -> bool {
119 let res = self.attrs.eq(&other.attrs) && self.tag.eq(&other.tag);
120
121 for (p, q) in self.children.iter().enumerate() {
122 if !q.eq(&other.children[p]) {
123 return false;
124 }
125 }
126
127 res
128 }
129}