moon-driver-utils 0.1.0

Windows Kernel Utils
use wdk_sys::LIST_ENTRY;

use crate::memory::{npp::NPP, AllocationError};

pub fn init_linked_list(list: &mut LIST_ENTRY) {
    list.Flink = list;
    list.Blink = list;
}

#[repr(C)]
pub struct LinkedList<T> {
    head: Option<NPP<Node<T>>>,
    size: usize,
}

#[repr(C)]
pub struct Node<T> {
    pub val: T,
    pub next: Option<NPP<Node<T>>>,
}

impl<T> Default for LinkedList<T> {
    fn default() -> Self {
        Self::new()
    }
}

impl<T> Drop for LinkedList<T> {
    fn drop(&mut self) {}
}

impl<T> LinkedList<T> {
    pub fn new() -> Self {
        Self {
            head: None,
            size: 0,
        }
    }

    pub fn is_empty(&self) -> bool {
        self.size == 0
    }
    pub fn len(&self) -> usize {
        self.size
    }

    pub fn push_head(&mut self, data: T) -> Result<&mut Self, AllocationError> {
        let node = NPP::new(Node {
            val: data,
            next: self.head.take(),
        })?;

        self.head = Some(node);
        self.size += 1;
        Ok(self)
    }

    pub fn iter_mut(&mut self) -> IterMut<T> {
        IterMut {
            current: self.head.as_deref_mut(),
        }
    }

    pub fn iter(&self) -> Iter<T> {
        Iter {
            current: self.head.as_deref(),
        }
    }
}

pub struct IterMut<'a, T> {
    current: Option<&'a mut Node<T>>,
}

impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;

    fn next(&mut self) -> Option<Self::Item> {
        self.current.take().map(|node| {
            self.current = node.next.as_deref_mut();
            &mut node.val
        })
    }
}

pub struct Iter<'a, T> {
    current: Option<&'a Node<T>>,
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        self.current.map(|node| {
            self.current = node.next.as_deref();
            &node.val
        })
    }
}