processes 0.4.0

A utility library for accessing processes and modules on windows.
Documentation
use std::{
    mem::{ManuallyDrop, MaybeUninit},
    ops::{Deref, DerefMut},
    ptr,
};

use super::{
    maybe_uninit_slice_assume_init_mut, maybe_uninit_slice_assume_init_ref,
    maybe_uninit_uninit_array,
};

#[derive(Debug)]
pub(crate) struct ArrayBuf<T, const SIZE: usize> {
    data: [MaybeUninit<T>; SIZE],
    len: usize,
}

impl<T, const SIZE: usize> ArrayBuf<T, SIZE> {
    pub fn new_uninit() -> Self {
        Self {
            data: maybe_uninit_uninit_array(),
            len: 0,
        }
    }

    pub fn from_array(mut array: [T; SIZE]) -> Self {
        let data = unsafe { ptr::read(&mut array as *mut _ as *mut [MaybeUninit<T>; SIZE]) };
        Self { data, len: SIZE }
    }

    pub fn from_partial_init_array(array: [MaybeUninit<T>; SIZE], len: usize) -> Self {
        Self { data: array, len }
    }

    pub fn len(&self) -> usize {
        self.len
    }

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

    pub fn capacity(&self) -> usize {
        SIZE
    }

    pub unsafe fn set_len(&mut self, new_len: usize) {
        assert!(new_len <= SIZE, "ArrayBuf::set_len: len > SIZE");
        self.len = new_len;
    }

    pub fn as_slice(&self) -> &[T] {
        unsafe { maybe_uninit_slice_assume_init_ref(&self.data[..self.len]) }
    }

    pub fn as_mut_slice(&mut self) -> &mut [T] {
        unsafe { maybe_uninit_slice_assume_init_mut(&mut self.data[..self.len]) }
    }

    pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
        &mut self.data[self.len..]
    }

    pub fn clear(&mut self) {
        for e in &mut self.data[0..self.len] {
            unsafe { e.assume_init_drop() };
        }
        self.len = 0;
    }

    pub fn to_vec(&self) -> Vec<T>
    where
        T: Copy,
    {
        let mut vec = Vec::with_capacity(self.len());
        vec.extend_from_slice(self.as_slice());
        vec
    }
}

impl<T, const SIZE: usize> AsRef<[T]> for ArrayBuf<T, SIZE> {
    fn as_ref(&self) -> &[T] {
        self.as_slice()
    }
}
impl<T, const SIZE: usize> AsMut<[T]> for ArrayBuf<T, SIZE> {
    fn as_mut(&mut self) -> &mut [T] {
        self.as_mut_slice()
    }
}

impl<T, const SIZE: usize> Deref for ArrayBuf<T, SIZE> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        self.as_ref()
    }
}

impl<T, const SIZE: usize> DerefMut for ArrayBuf<T, SIZE> {
    fn deref_mut(&mut self) -> &mut [T] {
        self.as_mut()
    }
}

impl<T, const SIZE: usize> From<[T; SIZE]> for ArrayBuf<T, SIZE> {
    fn from(array: [T; SIZE]) -> Self {
        Self::from_array(array)
    }
}

impl<T, const SIZE: usize> Drop for ArrayBuf<T, SIZE> {
    fn drop(&mut self) {
        self.clear();
    }
}

pub(crate) struct ArrayBufIter<T, const SIZE: usize> {
    buf: ManuallyDrop<ArrayBuf<T, SIZE>>,
    offset: usize,
}

impl<T, const SIZE: usize> IntoIterator for ArrayBuf<T, SIZE> {
    type Item = T;
    type IntoIter = ArrayBufIter<T, SIZE>;

    fn into_iter(self) -> Self::IntoIter {
        ArrayBufIter {
            buf: ManuallyDrop::new(self),
            offset: 0,
        }
    }
}

impl<T, const SIZE: usize> Iterator for ArrayBufIter<T, SIZE> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        if self.len() == 0 {
            return None;
        }

        let item = unsafe { MaybeUninit::assume_init_read(&self.buf.data[self.offset]) };
        self.offset += 1;
        Some(item)
    }
}

impl<T, const SIZE: usize> DoubleEndedIterator for ArrayBufIter<T, SIZE> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.len() == 0 {
            return None;
        }

        let item = unsafe { MaybeUninit::assume_init_read(&self.buf.data[self.buf.len - 1]) };
        self.buf.len -= 1;
        Some(item)
    }
}

impl<T, const SIZE: usize> ExactSizeIterator for ArrayBufIter<T, SIZE> {
    fn len(&self) -> usize {
        self.buf.len - self.offset
    }
}

impl<T, const SIZE: usize> Drop for ArrayBufIter<T, SIZE> {
    fn drop(&mut self) {
        let len = self.buf.len();
        for e in &mut self.buf.data[self.offset..len] {
            unsafe { e.assume_init_drop() };
        }
        self.buf.len = 0;
    }
}