summaryrefslogtreecommitdiff
path: root/crates/device_tree/src/stack_linked_list.rs
diff options
context:
space:
mode:
authorNathan Ringo <nathan@remexre.com>2024-09-01 19:59:44 -0500
committerNathan Ringo <nathan@remexre.com>2024-09-01 19:59:44 -0500
commit386df39c9866a4d945de46ef0dcab2363c674e0e (patch)
treec0572ce6a2c81c93546210f599dff553783c5760 /crates/device_tree/src/stack_linked_list.rs
parent6b98b6afea6e790abe738a67aa28bab54c91afe0 (diff)
Move almost all the kernel into crates/.
Diffstat (limited to 'crates/device_tree/src/stack_linked_list.rs')
-rw-r--r--crates/device_tree/src/stack_linked_list.rs78
1 files changed, 78 insertions, 0 deletions
diff --git a/crates/device_tree/src/stack_linked_list.rs b/crates/device_tree/src/stack_linked_list.rs
new file mode 100644
index 0000000..19b9272
--- /dev/null
+++ b/crates/device_tree/src/stack_linked_list.rs
@@ -0,0 +1,78 @@
+//! A linked list whose nodes can be stack-allocated.
+
+use core::fmt;
+
+/// A linked list whose nodes can be stack-allocated.
+#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
+pub struct StackLinkedList<'list, T>(Option<(T, &'list StackLinkedList<'list, T>)>);
+
+impl<'list, T> StackLinkedList<'list, T> {
+ /// An empty linked list.
+ pub const NIL: StackLinkedList<'list, T> = StackLinkedList(None);
+
+ /// Prepends an element to the linked list, returning the new head node.
+ pub fn cons(&'list self, head: T) -> StackLinkedList<'list, T> {
+ StackLinkedList(Some((head, self)))
+ }
+
+ /// Attempts to return the head and tail of the list.
+ pub fn uncons(&self) -> Option<(&T, &'list StackLinkedList<'list, T>)> {
+ let (hd, tl) = self.0.as_ref()?;
+ Some((hd, tl))
+ }
+
+ /// Returns an iterator over the elements in the list.
+ pub fn iter<'iter: 'list>(&'iter self) -> impl 'iter + Iterator<Item = &'list T> {
+ struct Iter<'iter, 'list, T>(&'iter StackLinkedList<'list, T>);
+
+ impl<'iter: 'list, 'list, T> Iterator for Iter<'iter, 'list, T> {
+ type Item = &'list T;
+
+ fn next(&mut self) -> Option<&'list T> {
+ match &(self.0).0 {
+ Some((hd, tl)) => {
+ self.0 = tl;
+ Some(hd)
+ }
+ None => None,
+ }
+ }
+ }
+
+ Iter(self)
+ }
+}
+
+impl<'list, T: fmt::Debug> fmt::Debug for StackLinkedList<'list, T> {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt.debug_list().entries(self.iter()).finish()
+ }
+}
+
+impl<'list, T: Copy> IntoIterator for StackLinkedList<'list, T> {
+ type Item = T;
+
+ type IntoIter = OwnedIter<'list, T>;
+
+ fn into_iter(self) -> OwnedIter<'list, T> {
+ OwnedIter(self)
+ }
+}
+
+/// An (owned) iterator over a `StackLinkedList`.
+#[derive(Clone)]
+pub struct OwnedIter<'list, T>(StackLinkedList<'list, T>);
+
+impl<'list, T: Copy> Iterator for OwnedIter<'list, T> {
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ match (self.0).0 {
+ Some((hd, tl)) => {
+ self.0 = *tl;
+ Some(hd)
+ }
+ None => None,
+ }
+ }
+}