summaryrefslogtreecommitdiff
path: root/kernel/src/collections
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src/collections')
-rw-r--r--kernel/src/collections/mod.rs3
-rw-r--r--kernel/src/collections/stack_linked_list.rs44
2 files changed, 47 insertions, 0 deletions
diff --git a/kernel/src/collections/mod.rs b/kernel/src/collections/mod.rs
new file mode 100644
index 0000000..ebcfad3
--- /dev/null
+++ b/kernel/src/collections/mod.rs
@@ -0,0 +1,3 @@
+//! Useful data structures for the kernel.
+
+pub mod stack_linked_list;
diff --git a/kernel/src/collections/stack_linked_list.rs b/kernel/src/collections/stack_linked_list.rs
new file mode 100644
index 0000000..ce9ee8e
--- /dev/null
+++ b/kernel/src/collections/stack_linked_list.rs
@@ -0,0 +1,44 @@
+//! 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>(pub 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)))
+ }
+
+ /// 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()
+ }
+}