1use alloc::vec::Vec;
21use core::{
22 ops::{Index, IndexMut},
23 slice::Iter,
24};
25
26pub use self::node_id::NodeId;
27use crate::styled_dom::NodeHierarchyItem;
28
29pub type NodeDepths = Vec<(usize, NodeId)>;
31
32pub mod node_id {
34
35 use alloc::vec::Vec;
36 use core::{
37 fmt,
38 ops::{Add, AddAssign},
39 };
40
41 #[repr(C)]
70 #[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
71 pub struct NodeId {
72 inner: usize,
75 }
76
77 impl NodeId {
78 pub const ZERO: Self = Self { inner: 0 };
80
81 #[inline]
83 #[must_use]
84 pub const fn new(value: usize) -> Self {
85 Self { inner: value }
86 }
87
88 #[inline]
101 #[must_use]
102 pub const fn from_usize(value: usize) -> Option<Self> {
103 match value {
104 0 => None,
105 i => Some(Self { inner: i - 1 }),
106 }
107 }
108
109 #[inline]
118 #[must_use]
119 pub const fn into_raw(val: &Option<Self>) -> usize {
120 match val {
121 None => 0,
122 Some(s) => s.inner + 1,
123 }
124 }
125
126 #[inline]
130 #[must_use]
131 pub const fn index(&self) -> usize {
132 self.inner
133 }
134 }
135
136 impl From<usize> for NodeId {
137 fn from(val: usize) -> Self {
138 Self::new(val)
139 }
140 }
141
142 impl From<NodeId> for usize {
143 fn from(val: NodeId) -> Self {
144 val.inner
145 }
146 }
147
148 impl Add<usize> for NodeId {
149 type Output = Self;
150 #[inline]
156 fn add(self, other: usize) -> Self {
157 Self::new(self.inner.saturating_add(other))
158 }
159 }
160
161 impl AddAssign<usize> for NodeId {
162 #[inline]
164 fn add_assign(&mut self, other: usize) {
165 *self = *self + other;
166 }
167 }
168
169 impl fmt::Display for NodeId {
170 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171 write!(f, "{}", self.inner)
172 }
173 }
174
175 impl fmt::Debug for NodeId {
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 write!(f, "NodeId({})", self.inner)
178 }
179 }
180}
181
182#[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
184pub struct Node {
185 pub parent: Option<NodeId>,
186 pub previous_sibling: Option<NodeId>,
187 pub next_sibling: Option<NodeId>,
188 pub last_child: Option<NodeId>,
189 }
198
199impl Node {
200 pub const ROOT: Self = Self {
201 parent: None,
202 previous_sibling: None,
203 next_sibling: None,
204 last_child: None,
205 };
206
207 #[inline]
208 #[must_use]
209 pub const fn has_parent(&self) -> bool {
210 self.parent.is_some()
211 }
212 #[inline]
213 #[must_use]
214 pub const fn has_previous_sibling(&self) -> bool {
215 self.previous_sibling.is_some()
216 }
217 #[inline]
218 #[must_use]
219 pub const fn has_next_sibling(&self) -> bool {
220 self.next_sibling.is_some()
221 }
222 #[inline]
223 #[must_use]
224 pub const fn has_first_child(&self) -> bool {
225 self.last_child.is_some() }
227 #[inline]
228 #[must_use]
229 pub const fn has_last_child(&self) -> bool {
230 self.last_child.is_some()
231 }
232
233 #[inline]
234 #[must_use]
235 pub fn get_first_child(&self, current_node_id: NodeId) -> Option<NodeId> {
236 self.last_child.map(|_| current_node_id + 1)
238 }
239}
240
241#[derive(Debug, Default, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
245pub struct NodeHierarchy {
246 pub internal: Vec<Node>,
247}
248
249impl NodeHierarchy {
250 #[inline]
251 #[must_use]
252 pub const fn new(data: Vec<Node>) -> Self {
253 Self { internal: data }
254 }
255
256 #[inline]
257 #[must_use]
258 pub fn as_ref(&self) -> NodeHierarchyRef<'_> {
259 NodeHierarchyRef {
260 internal: &self.internal[..],
261 }
262 }
263}
264
265#[derive(Debug, PartialEq, Hash, Eq)]
269pub struct NodeHierarchyRef<'a> {
270 pub internal: &'a [Node],
271}
272
273impl<'a> NodeHierarchyRef<'a> {
274 #[inline]
275 #[must_use]
276 pub const fn from_slice(data: &'a [Node]) -> Self {
277 NodeHierarchyRef { internal: data }
278 }
279
280 #[inline]
281 #[must_use]
282 pub const fn len(&self) -> usize {
283 self.internal.len()
284 }
285
286 #[inline]
287 #[must_use]
288 pub const fn is_empty(&self) -> bool {
289 self.internal.is_empty()
290 }
291
292 #[inline]
293 #[must_use]
294 pub fn get(&self, id: NodeId) -> Option<&Node> {
295 self.internal.get(id.index())
296 }
297
298 #[inline]
299 #[must_use]
300 pub const fn linear_iter(&self) -> LinearIterator {
301 LinearIterator {
302 arena_len: self.len(),
303 position: 0,
304 }
305 }
306
307 #[allow(clippy::iter_with_drain)]
315 #[must_use]
316 pub fn get_parents_sorted_by_depth(&self) -> NodeDepths {
317 if self.is_empty() {
320 return Vec::new();
321 }
322
323 let root = NodeId::new(0);
324 let mut non_leaf_nodes = Vec::new();
325
326 if !self[root].has_first_child() {
332 return non_leaf_nodes;
333 }
334
335 let mut current_children = vec![(0, root)];
336 let mut next_children = Vec::new();
337 let mut depth = 1_usize;
338
339 loop {
340 for id in ¤t_children {
341 for child_id in id.1.children(self).filter(|id| self[*id].has_first_child()) {
342 next_children.push((depth, child_id));
343 }
344 }
345
346 non_leaf_nodes.extend(&mut current_children.drain(..));
347
348 if next_children.is_empty() {
349 break;
350 }
351 current_children.extend(&mut next_children.drain(..));
352 depth += 1;
353 }
354
355 non_leaf_nodes
356 }
357}
358
359#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
360pub struct NodeDataContainer<T> {
361 pub internal: Vec<T>,
362}
363
364impl<T> From<Vec<T>> for NodeDataContainer<T> {
365 fn from(v: Vec<T>) -> Self {
366 Self { internal: v }
367 }
368}
369
370#[derive(Debug, PartialEq, Hash, Eq, PartialOrd, Ord)]
371pub struct NodeDataContainerRef<'a, T> {
372 pub internal: &'a [T],
373}
374
375#[derive(Debug, PartialEq, Hash, Eq, PartialOrd, Ord)]
376pub struct NodeDataContainerRefMut<'a, T> {
377 pub internal: &'a mut [T],
378}
379
380impl<T> Default for NodeDataContainer<T> {
381 fn default() -> Self {
382 Self {
383 internal: Vec::new(),
384 }
385 }
386}
387
388impl Index<NodeId> for NodeHierarchyRef<'_> {
389 type Output = Node;
390
391 #[inline]
392 fn index(&self, node_id: NodeId) -> &Node {
393 &self.internal[node_id.index()]
394 }
395}
396
397impl<T> NodeDataContainer<T> {
398 #[inline]
399 #[must_use]
400 pub const fn new(data: Vec<T>) -> Self {
401 Self { internal: data }
402 }
403
404 #[inline]
405 #[must_use]
406 pub const fn is_empty(&self) -> bool {
407 self.internal.is_empty()
408 }
409
410 #[inline]
411 #[must_use]
412 pub fn as_ref(&self) -> NodeDataContainerRef<'_, T> {
413 NodeDataContainerRef {
414 internal: &self.internal[..],
415 }
416 }
417
418 #[inline]
419 pub fn as_ref_mut(&mut self) -> NodeDataContainerRefMut<'_, T> {
420 NodeDataContainerRefMut {
421 internal: &mut self.internal[..],
422 }
423 }
424
425 #[inline]
426 #[must_use]
427 pub const fn len(&self) -> usize {
428 self.internal.len()
429 }
430}
431
432impl<'a, T: 'a> NodeDataContainerRefMut<'a, T> {
433 #[inline]
434 pub const fn from_slice(data: &'a mut [T]) -> Self {
435 NodeDataContainerRefMut { internal: data }
436 }
437}
438
439impl<'a, T: 'a> NodeDataContainerRefMut<'a, T> {
440 #[inline]
441 pub fn get_mut(&mut self, id: NodeId) -> Option<&mut T> {
442 self.internal.get_mut(id.index())
443 }
444}
445
446impl<'a, T: Send + 'a> NodeDataContainerRef<'a, T> {
447 pub fn transform_nodeid_optional<U: Send, F>(&self, closure: F) -> NodeDataContainer<U>
448 where
449 F: Send + Sync + Fn(NodeId) -> Option<U>,
450 {
451 let len = self.len();
452 NodeDataContainer {
453 internal: (0..len)
454 .filter_map(|node_id| closure(NodeId::new(node_id)))
455 .collect::<Vec<U>>(),
456 }
457 }
458}
459
460impl<'a, T> IntoIterator for &NodeDataContainerRef<'a, T> {
461 type Item = &'a T;
462 type IntoIter = Iter<'a, T>;
463 #[inline]
464 fn into_iter(self) -> Self::IntoIter {
465 self.internal.iter()
466 }
467}
468
469impl<'a, T: 'a> NodeDataContainerRef<'a, T> {
470 #[inline]
471 pub const fn from_slice(data: &'a [T]) -> Self {
472 NodeDataContainerRef { internal: data }
473 }
474
475 #[inline]
476 #[must_use]
477 pub const fn len(&self) -> usize {
478 self.internal.len()
479 }
480
481 #[inline]
482 #[must_use]
483 pub const fn is_empty(&self) -> bool {
484 self.internal.is_empty()
485 }
486
487 #[inline]
488 #[must_use]
489 pub fn get(&self, id: NodeId) -> Option<&T> {
490 self.internal.get(id.index())
491 }
492
493 #[inline]
494 pub fn iter(&self) -> Iter<'_, T> {
495 self.internal.iter()
496 }
497
498 #[inline]
499 #[must_use]
500 pub const fn linear_iter(&self) -> LinearIterator {
501 LinearIterator {
502 arena_len: self.len(),
503 position: 0,
504 }
505 }
506}
507
508impl<T> Index<NodeId> for NodeDataContainerRef<'_, T> {
509 type Output = T;
510
511 #[inline]
512 fn index(&self, node_id: NodeId) -> &T {
513 &self.internal[node_id.index()]
514 }
515}
516
517impl<T> Index<NodeId> for NodeDataContainerRefMut<'_, T> {
518 type Output = T;
519
520 #[inline]
521 fn index(&self, node_id: NodeId) -> &T {
522 &self.internal[node_id.index()]
523 }
524}
525
526impl<T> IndexMut<NodeId> for NodeDataContainerRefMut<'_, T> {
527 #[inline]
528 fn index_mut(&mut self, node_id: NodeId) -> &mut T {
529 &mut self.internal[node_id.index()]
530 }
531}
532
533impl NodeId {
534 #[inline]
538 #[must_use]
539 pub const fn preceding_siblings<'a>(
540 self,
541 node_hierarchy: &'a NodeHierarchyRef<'a>,
542 ) -> PrecedingSiblings<'a> {
543 PrecedingSiblings {
544 node_hierarchy,
545 node: Some(self),
546 }
547 }
548
549 #[inline]
551 #[must_use]
552 pub fn children<'a>(self, node_hierarchy: &'a NodeHierarchyRef<'a>) -> Children<'a> {
553 Children {
554 node_hierarchy,
555 node: node_hierarchy[self].get_first_child(self),
556 }
557 }
558}
559
560macro_rules! impl_node_iterator {
561 ($name:ident, $next:expr) => {
562 impl Iterator for $name<'_> {
563 type Item = NodeId;
564
565 fn next(&mut self) -> Option<NodeId> {
566 match self.node.take() {
567 Some(node) => {
568 self.node = $next(&self.node_hierarchy[node]);
569 Some(node)
570 }
571 None => None,
572 }
573 }
574 }
575 };
576}
577
578#[derive(Debug, Clone)]
581pub struct LinearIterator {
582 arena_len: usize,
583 position: usize,
584}
585
586impl Iterator for LinearIterator {
587 type Item = NodeId;
588
589 fn next(&mut self) -> Option<NodeId> {
590 if self.arena_len < 1 || self.position > (self.arena_len - 1) {
591 None
592 } else {
593 let new_id = Some(NodeId::new(self.position));
594 self.position += 1;
595 new_id
596 }
597 }
598}
599
600#[derive(Debug)]
602pub struct PrecedingSiblings<'a> {
603 node_hierarchy: &'a NodeHierarchyRef<'a>,
604 node: Option<NodeId>,
605}
606
607impl_node_iterator!(PrecedingSiblings, |node: &Node| node.previous_sibling);
608
609#[derive(Debug)]
611pub struct AzChildren<'a> {
612 node_hierarchy: &'a NodeDataContainerRef<'a, NodeHierarchyItem>,
613 node: Option<NodeId>,
614}
615
616impl Iterator for AzChildren<'_> {
617 type Item = NodeId;
618
619 fn next(&mut self) -> Option<NodeId> {
620 match self.node.take() {
621 Some(node) => {
622 self.node = self.node_hierarchy[node].next_sibling_id();
623 Some(node)
624 }
625 None => None,
626 }
627 }
628}
629
630#[derive(Debug)]
632pub struct AzReverseChildren<'a> {
633 node_hierarchy: &'a NodeDataContainerRef<'a, NodeHierarchyItem>,
634 node: Option<NodeId>,
635}
636
637impl Iterator for AzReverseChildren<'_> {
638 type Item = NodeId;
639
640 fn next(&mut self) -> Option<NodeId> {
641 match self.node.take() {
642 Some(node) => {
643 self.node = self.node_hierarchy[node].previous_sibling_id();
644 Some(node)
645 }
646 None => None,
647 }
648 }
649}
650
651impl NodeId {
652 pub fn get_nearest_matching_parent<'a, F>(
657 self,
658 node_hierarchy: &'a NodeDataContainerRef<'a, NodeHierarchyItem>,
659 predicate: F,
660 ) -> Option<Self>
661 where
662 F: Fn(Self) -> bool,
663 {
664 let node_count = node_hierarchy.internal.len();
669 let mut current_node = node_hierarchy.internal.get(self.index())?.parent_id()?;
670 for _ in 0..node_count {
671 if predicate(current_node) {
672 return Some(current_node);
673 }
674 current_node = node_hierarchy
675 .internal
676 .get(current_node.index())?
677 .parent_id()?;
678 }
679 None
680 }
681
682 #[inline]
684 #[must_use]
685 pub fn az_children_collect<'a>(
686 self,
687 node_hierarchy: &'a NodeDataContainerRef<'a, NodeHierarchyItem>,
688 ) -> Vec<Self> {
689 self.az_children(node_hierarchy).collect()
690 }
691
692 #[inline]
694 #[must_use]
695 pub fn az_children<'a>(
696 self,
697 node_hierarchy: &'a NodeDataContainerRef<'a, NodeHierarchyItem>,
698 ) -> AzChildren<'a> {
699 AzChildren {
700 node_hierarchy,
701 node: node_hierarchy[self].first_child_id(self),
702 }
703 }
704
705 #[inline]
707 #[must_use]
708 pub fn az_reverse_children<'a>(
709 self,
710 node_hierarchy: &'a NodeDataContainerRef<'a, NodeHierarchyItem>,
711 ) -> AzReverseChildren<'a> {
712 AzReverseChildren {
713 node_hierarchy,
714 node: node_hierarchy[self].last_child_id(),
715 }
716 }
717}
718
719#[derive(Debug)]
721pub struct Children<'a> {
722 node_hierarchy: &'a NodeHierarchyRef<'a>,
723 node: Option<NodeId>,
724}
725
726impl_node_iterator!(Children, |node: &Node| node.next_sibling);
727
728#[cfg(test)]
729#[path = "id_test.rs"]
730mod id_test;
731
732azul_css::impl_option!(
735 NodeId,
736 OptionNodeId,
737 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
738);