dll-syringe 0.11.3

A windows dll injection library written in rust.
Documentation
use std::{
    mem::MaybeUninit,
    ops::{Deref, DerefMut},
    vec,
};

use super::{ArrayBuf, ArrayBufIter};

#[derive(Debug)]
pub(crate) enum ArrayOrVecBuf<T, const SIZE: usize> {
    Array(ArrayBuf<T, SIZE>),
    Vec(Vec<T>),
}

impl<T, const SIZE: usize> Default for ArrayOrVecBuf<T, SIZE> {
    fn default() -> Self {
        Self::Vec(Vec::new())
    }
}

impl<T, const SIZE: usize> ArrayOrVecBuf<T, SIZE> {
    pub fn with_capacity(capacity: usize) -> Self {
        if capacity <= SIZE {
            Self::new_uninit_array()
        } else {
            Self::Vec(Vec::with_capacity(capacity))
        }
    }

    pub fn new_uninit_array() -> Self {
        Self::from_partial_init_array(MaybeUninit::uninit_array(), 0)
    }

    pub fn from_array(array: [T; SIZE]) -> Self {
        Self::Array(ArrayBuf::from_array(array))
    }

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

    pub fn from_vec(vec: Vec<T>) -> Self {
        Self::Vec(vec)
    }

    pub fn len(&self) -> usize {
        match self {
            ArrayOrVecBuf::Array(array) => array.len(),
            ArrayOrVecBuf::Vec(vec) => vec.len(),
        }
    }

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

    pub fn capacity(&self) -> usize {
        match self {
            ArrayOrVecBuf::Array(array) => array.capacity(),
            ArrayOrVecBuf::Vec(vec) => vec.capacity(),
        }
    }

    pub unsafe fn set_len(&mut self, new_len: usize) {
        match self {
            ArrayOrVecBuf::Array(array) => unsafe { array.set_len(new_len) },
            ArrayOrVecBuf::Vec(vec) => unsafe { vec.set_len(new_len) },
        }
    }

    pub fn clear(&mut self) {
        match self {
            ArrayOrVecBuf::Array(array) => array.clear(),
            ArrayOrVecBuf::Vec(vec) => vec.clear(),
        }
    }

    pub fn as_slice(&self) -> &[T] {
        match self {
            ArrayOrVecBuf::Array(array) => array.as_slice(),
            ArrayOrVecBuf::Vec(vec) => vec.as_slice(),
        }
    }

    pub fn as_mut_slice(&mut self) -> &mut [T] {
        match self {
            ArrayOrVecBuf::Array(array) => array.as_mut_slice(),
            ArrayOrVecBuf::Vec(vec) => vec.as_mut_slice(),
        }
    }

    pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
        match self {
            ArrayOrVecBuf::Array(array) => array.spare_capacity_mut(),
            ArrayOrVecBuf::Vec(vec) => vec.spare_capacity_mut(),
        }
    }

    pub fn into_vec(self) -> Vec<T>
    where
        T: Copy,
    {
        match self {
            Self::Array(array) => array.to_vec(),
            Self::Vec(vec) => vec,
        }
    }

    pub fn ensure_capacity(&mut self, capacity: usize)
    where
        T: Copy,
    {
        match self {
            ArrayOrVecBuf::Array { .. } => {
                if SIZE >= capacity {
                    return;
                }

                let mut vec = Vec::with_capacity(capacity);
                vec.copy_from_slice(self.as_slice());
                *self = Self::Vec(vec);
            }
            ArrayOrVecBuf::Vec(vec) => {
                if vec.capacity() >= capacity {
                    return;
                }

                vec.reserve(capacity - vec.capacity());
            }
        }
    }
}

impl<const SIZE: usize> ArrayOrVecBuf<u8, SIZE> {
    pub fn spare_writer(&mut self) -> impl std::io::Write + '_ {
        let spare = self.spare_capacity_mut();
        unsafe { MaybeUninit::slice_assume_init_mut(spare) }
    }
}

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

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

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

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

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

impl<T, const SIZE: usize> From<Vec<T>> for ArrayOrVecBuf<T, SIZE> {
    fn from(vec: Vec<T>) -> Self {
        Self::from_vec(vec)
    }
}

pub(crate) enum ArrayOrVecBufIter<T, const SIZE: usize> {
    Array(ArrayBufIter<T, SIZE>),
    Vec(vec::IntoIter<T>),
}

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

    fn into_iter(self) -> Self::IntoIter {
        match self {
            Self::Array(array) => ArrayOrVecBufIter::Array(array.into_iter()),
            Self::Vec(vec) => ArrayOrVecBufIter::Vec(vec.into_iter()),
        }
    }
}

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

    fn next(&mut self) -> Option<Self::Item> {
        match self {
            ArrayOrVecBufIter::Array(array) => array.next(),
            ArrayOrVecBufIter::Vec(iter) => iter.next(),
        }
    }
}

impl<T, const SIZE: usize> DoubleEndedIterator for ArrayOrVecBufIter<T, SIZE> {
    fn next_back(&mut self) -> Option<Self::Item> {
        match self {
            ArrayOrVecBufIter::Array(iter) => iter.next_back(),
            ArrayOrVecBufIter::Vec(iter) => iter.next_back(),
        }
    }
}

impl<T, const SIZE: usize> ExactSizeIterator for ArrayOrVecBufIter<T, SIZE> {
    fn len(&self) -> usize {
        match self {
            ArrayOrVecBufIter::Array(iter) => iter.len(),
            ArrayOrVecBufIter::Vec(iter) => iter.len(),
        }
    }
}