1use crate::{Attribute, Class, GestureKV, StateKV, Style, StyleWrapper};
2use elvis_core_support::Wrapper;
3use std::{
4 cell::RefCell,
5 collections::hash_map::DefaultHasher,
6 fmt,
7 hash::Hasher,
8 rc::{Rc, Weak},
9};
10
11fn hash(s: &[u8]) -> String {
12 let mut hasher = DefaultHasher::new();
13 hasher.write(s);
14
15 let res = format!("{:x}", hasher.finish());
16 format!("elvis-{}", &res[0..6])
17}
18
19#[derive(Clone, Default, Wrapper)]
21pub struct Node {
22 pub attr: Attribute,
24 pub class: Vec<Class>,
26 pub style: Vec<Style>,
28 pub children: Vec<Rc<RefCell<Node>>>,
30 pub pre: Option<Weak<RefCell<Node>>>,
32 pub state: Option<StateKV>,
34 pub gesture: Option<GestureKV>,
36}
37
38impl fmt::Debug for Node {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 f.debug_struct("Node")
41 .field("children", &self.children)
42 .field("pre", &self.pre)
43 .finish()
44 }
45}
46
47impl Node {
48 pub fn attr(mut self, attr: Attribute) -> Node {
50 self.attr = attr;
51 self
52 }
53
54 pub fn children(mut self, children: Vec<Node>) -> Node {
56 self.children = children
57 .iter()
58 .map(|n| Rc::new(RefCell::new(n.clone())))
59 .collect::<Vec<Rc<RefCell<Node>>>>();
60 self
61 }
62
63 pub fn append_child(mut self, child: Node) -> Node {
65 self.children.push(Rc::new(RefCell::new(child)));
66 self
67 }
68
69 pub fn append_children(mut self, children: Vec<Node>) -> Node {
71 self.children.append(
72 &mut children
73 .iter()
74 .map(|n| Rc::new(RefCell::new(n.clone())))
75 .collect::<Vec<Rc<RefCell<Node>>>>(),
76 );
77 self
78 }
79
80 pub fn class(mut self, class: Vec<Class>) -> Node {
82 self.class = class;
83 self
84 }
85
86 pub fn append_class(mut self, class: &mut Vec<Class>) -> Node {
88 self.class.append(class);
89 self.class.sort();
90 self.class.dedup();
91 self
92 }
93
94 pub fn style(mut self, style: impl Into<Vec<Style>>) -> Node {
96 self.style = style.into();
97 self
98 }
99
100 pub fn append_style(mut self, styles: impl Into<Vec<Style>>) -> Node {
102 self.style.append(&mut styles.into());
103 self.style.sort();
104 self.style.dedup();
105 self
106 }
107
108 pub fn drain(t: Rc<RefCell<Node>>) {
110 if let Some(pre) = &t.borrow().pre {
111 let u = pre.upgrade().expect("drain child failed");
112 u.borrow_mut().remove(t.clone());
113 u.borrow_mut().update();
114 }
115 }
116
117 pub fn idx(&mut self, path: &mut Vec<u8>) {
119 self.attr.id = hash(&path);
120
121 path.push(0);
122 for t in self.children.iter() {
123 t.borrow_mut().idx(path);
124 if let Some(last) = path.last_mut() {
125 *last += 1;
126 }
127 }
128 }
129
130 pub fn locate(&self, mut path: Vec<usize>) -> Vec<usize> {
132 if let Some(pre) = &self.pre {
133 let u = pre.upgrade().expect("locate widget failed");
134 for (i, t) in u.borrow().children.iter().enumerate() {
135 if t.borrow().eq(self) {
136 path.push(i);
137 return u.borrow().locate(path);
138 }
139 }
140 }
141
142 path
143 }
144
145 pub fn push(r: Rc<RefCell<Node>>, c: Rc<RefCell<Node>>) {
152 let pre = Rc::downgrade(&r);
153 c.borrow_mut().pre = Some(pre.clone());
154
155 pre.upgrade()
156 .expect("push child to tree failed")
157 .borrow_mut()
158 .children
159 .push(c);
160
161 r.borrow_mut().update();
162 }
163
164 pub fn remove(&mut self, c: Rc<RefCell<Node>>) {
166 self.children.retain(|x| x != &c);
167 self.update();
168 }
169
170 pub fn replace(&mut self, mut t: Node) {
172 t.pre = self.pre.clone();
173 std::mem::swap(self, &mut t);
174
175 t.update();
176 }
177
178 pub fn update(&mut self) {}
180}
181
182impl PartialEq for Node {
183 fn eq(&self, other: &Self) -> bool {
184 let res =
185 self.attr.eq(&other.attr) && self.style.eq(&other.style) && self.class.eq(&other.class);
186
187 for (p, q) in self.children.iter().enumerate() {
188 if !q.eq(&other.children[p]) {
189 return false;
190 }
191 }
192
193 res
194 }
195}
196
197impl Eq for Node {}