4 releases
0.1.3 | Sep 9, 2023 |
---|---|
0.1.2 | Sep 7, 2023 |
0.1.1 | Sep 7, 2023 |
0.1.0 | Sep 7, 2023 |
#1902 in Data structures
58KB
1K
SLoC
hedel-rs
A Hierarchical Doubly Linked List
Hedel-rs provides all you need to create your own abstraction over a
hierarchical doubly linked list in Rust, suitable choice for a DOM tree.
Designed for when you need a nested generation of nodes. ( e.g with macros node!(1, node!(2))
)
Based on Rc
, Weak
, and a safe wrapper around UnsafeCell
(HedelCell
).
If you are new to linked lists, consider reading Learn Rust With Entirely Too Many Linked Lists
Ideology
Hedel isn't exactly a tree structure.
NodeList
is a wrap around its first node. There isn't any root. This allows for sibling nodes at the root-level.NodeList
also dereferences to its firt node letting you callNode
's methods.Node
is a pointer to its content and other pointers to allow navigation. Those pointers are:parent
,child
,prev
andnext
, where child is a pointer to its first child.- Support for node generation using macros: you can use node!(1) and nest how many nodes you want.
Features
-
HedelCell
: a cell structure safely relying on UnsafeCell, similar toRefCell
but smaller in size. -
Node
/WeakNode
: to avoid memory-leaking we also provide a weak version ofNode
. -
Macros: generate nodes blazingly fast with node!() and list!()
let node = node!(45); let my_node = node!("Parent", node!("Child"), node!("Child") ); let my_list = list!( node!(2), node!(3) );
-
Identify and compare: create your own identifier implementing the
CompareNode
trait.pub enum NumIdent { Equal(i32), BiggerThan(i32), SmallerThan(i32) } impl CompareNode<i32> for NumIdent { fn compare(&self, node: &Node<i32>) -> bool { match &self { Equal(n) => { as_content!(node, |content| { return content == &n; }); }, BiggerThan(n) => { as_content!(node, |content| { return content > &n; }); }, SmallerThan(n) => { as_content!(node, |content| { return content < &n; }); } } } } fn main() { let node = node!(3); assert!(NumIdent::BiggerThan(2).compare(&node)); }
-
Collect: iterate over the linked list and collect only the nodes matching the identifier.
let node = node!(1, node!(2), node!(3), node!(4), node!(5) ); let collection = node.collect_children(&NumIdent::BiggerThan(3)); for node in collection.into_iter() { println!("{}" node.to_content()); }
-
Detach: detach the nodes matching an identifier in the linked list.
let node = node!(1 node!(2), node!(3), node!(4), node!(5) ); let three = node.find_child(&NumIdent::Equal(3)).unwrap(); three.detach(); assert_eq!(node.find_child(&NumIdent::Equal(3)), None);
-
Insert or Append: insert a node at any position in a linked list.
let node = node!(1, node!(3), node!(4), node!(5) ); node.insert_child(0, node!(2)); assert_eq!(node.child().unwrap().to_content(), 2); node.append_child(node!(6)); assert_eq!(node.get_last_child().unwrap().to_content(), 6);
Dependencies
~225–670KB
~16K SLoC