dll-syringe 0.9.0

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

use crate::utils;

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

impl<T, const SIZE: usize> AsRef<[T]> for ArrayOrVec<T, SIZE> {
    fn as_ref(&self) -> &[T] {
        match self {
            ArrayOrVec::Array(ref array) => array.as_ref(),
            ArrayOrVec::Vec(ref vec) => vec.as_ref(),
        }
    }
}

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

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

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

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

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

impl<'a, T, const SIZE: usize> From<&'a ArrayOrVec<T, SIZE>> for &'a [T] {
    fn from(array_or_vec: &'a ArrayOrVec<T, SIZE>) -> Self {
        array_or_vec.as_ref()
    }
}

pub(crate) enum ArrayOrVecIter<T, const SIZE: usize> {
    Array(<[T; SIZE] as IntoIterator>::IntoIter),
    Vec(<Vec<T> as IntoIterator>::IntoIter),
}

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

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

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

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

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

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

#[derive(Debug)]
pub(crate) struct ArrayOrVecSlice<T, const SIZE: usize> {
    data: ArrayOrVec<T, SIZE>,
    range: Range<usize>,
}

impl<T, const SIZE: usize> ArrayOrVecSlice<T, SIZE> {
    pub fn from_array(array: [T; SIZE], range: impl RangeBounds<usize>) -> Self {
        Self {
            range: utils::range_from_bounds(0, array.len(), &range),
            data: ArrayOrVec::Array(array),
        }
    }

    #[allow(dead_code)]
    pub unsafe fn from_array_assume_init(
        array: [MaybeUninit<T>; SIZE],
        range: impl RangeBounds<usize>,
    ) -> Self {
        Self::from_array(unsafe { MaybeUninit::array_assume_init(array) }, range)
    }

    pub fn from_vec(vec: Vec<T>, range: impl RangeBounds<usize>) -> Self {
        Self {
            range: utils::range_from_bounds(0, vec.len(), &range),
            data: ArrayOrVec::Vec(vec),
        }
    }

    pub unsafe fn from_vec_assume_init(
        vec: Vec<MaybeUninit<T>>,
        range: impl RangeBounds<usize>,
    ) -> Self {
        let (ptr, length, capacity) = vec.into_raw_parts();
        Self::from_vec(
            unsafe { Vec::from_raw_parts(ptr.cast(), length, capacity) },
            range,
        )
    }

    #[allow(dead_code)]
    pub fn as_slice(&self) -> &[T] {
        match self.data {
            ArrayOrVec::Array(ref array) => &array[self.range.start..self.range.end],
            ArrayOrVec::Vec(ref vec) => &vec[self.range.start..self.range.end],
        }
    }
}

impl<T, const SIZE: usize> AsRef<[T]> for ArrayOrVecSlice<T, SIZE> {
    fn as_ref(&self) -> &[T] {
        &self.data.as_ref()[self.range.start..self.range.end]
    }
}

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

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

impl<T, const SIZE: usize> From<ArrayOrVec<T, SIZE>> for ArrayOrVecSlice<T, SIZE> {
    fn from(array_or_vec: ArrayOrVec<T, SIZE>) -> Self {
        Self {
            range: Range {
                start: 0,
                end: array_or_vec.len(),
            },
            data: array_or_vec,
        }
    }
}

pub(crate) struct ArrayOrVecSliceIter<T, const SIZE: usize>(
    std::iter::Skip<std::iter::Take<ArrayOrVecIter<T, SIZE>>>,
);

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

    fn into_iter(self) -> Self::IntoIter {
        ArrayOrVecSliceIter(
            self.data
                .into_iter()
                .take(self.range.end)
                .skip(self.range.start),
        )
    }
}

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

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

impl<T, const SIZE: usize> DoubleEndedIterator for ArrayOrVecSliceIter<T, SIZE> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.0.next_back()
    }
}

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