elvis_core/
node.rs

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/// Virtual UI Node
20#[derive(Clone, Default, Wrapper)]
21pub struct Node {
22    /// Node attribute
23    pub attr: Attribute,
24    /// Node Class
25    pub class: Vec<Class>,
26    /// Node Class
27    pub style: Vec<Style>,
28    /// Node children
29    pub children: Vec<Rc<RefCell<Node>>>,
30    /// Node parent
31    pub pre: Option<Weak<RefCell<Node>>>,
32    /// Node state
33    pub state: Option<StateKV>,
34    /// Node Gestures
35    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    /// Set attribute
49    pub fn attr(mut self, attr: Attribute) -> Node {
50        self.attr = attr;
51        self
52    }
53
54    /// Set Children
55    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    /// append child
64    pub fn append_child(mut self, child: Node) -> Node {
65        self.children.push(Rc::new(RefCell::new(child)));
66        self
67    }
68
69    /// append children
70    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    /// Set class
81    pub fn class(mut self, class: Vec<Class>) -> Node {
82        self.class = class;
83        self
84    }
85
86    /// Append class
87    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    /// Set style
95    pub fn style(mut self, style: impl Into<Vec<Style>>) -> Node {
96        self.style = style.into();
97        self
98    }
99
100    /// Append style
101    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    /// Drain tree if not the root
109    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    /// The path of current node
118    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    /// Locate tree
131    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    // /// Generate a `Rc<RefCell<Node>>`
146    // pub fn new() -> Rc<RefCell<Node>> {
147    //     Rc::new(RefCell::new(Node::default()))
148    // }
149
150    /// Add second tree to the first one.
151    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    /// Delete spefic child using rc
165    pub fn remove(&mut self, c: Rc<RefCell<Node>>) {
166        self.children.retain(|x| x != &c);
167        self.update();
168    }
169
170    /// Replace current tree
171    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    /// Update tree
179    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 {}