log-terminal 0.1.3

Terminal manager for displaying outputs/errors of processes launched from rust code.
Documentation
use std::{
    marker::PhantomData,
    ops::{Deref, DerefMut},
};

pub struct TypedVec<I: AsRef<usize>, T>(Vec<T>, PhantomData<I>);

impl<I, T> TypedVec<I, T>
where
    I: From<usize> + AsRef<usize>,
{
    pub fn new() -> Self {
        Self(Vec::new(), PhantomData)
    }

    pub fn from(vec: Vec<T>) -> Self {
        Self(vec, PhantomData)
    }

    pub fn get(&self, index: I) -> Option<&T> {
        self.0.get(*index.as_ref())
    }

    pub fn get_mut(&mut self, index: I) -> Option<&mut T> {
        self.0.get_mut(*index.as_ref())
    }

    pub fn remove(&mut self, index: I) -> T {
        self.0.remove(*index.as_ref())
    }

    pub fn len(&self) -> I {
        I::from(self.0.len())
    }
}

impl<I: AsRef<usize>, T> Deref for TypedVec<I, T> {
    type Target = Vec<T>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<I: AsRef<usize>, T> DerefMut for TypedVec<I, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

macro_rules! generate_index {
    ($($ident:ident),*) => {
        $(
        #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
        pub struct $ident(pub usize);

        impl AsRef<usize> for $ident {
            fn as_ref(&self) -> &usize {
                &self.0
            }
        }

        impl Deref for $ident {
            type Target = usize;
            fn deref(&self) -> &Self::Target {
                &self.0
            }
        }

        impl From<usize> for $ident {
            fn from(value: usize) -> Self {
                Self(value)
            }
        }

        impl $ident {
            pub fn manipulate<R: Manipulable<Self>>(self, f: impl FnOnce(usize) -> R) -> R::Return {
                f(self.0).map()
            }
        }

        impl Manipulable<$ident> for usize {
            type Return = $ident;

            fn map(self) -> $ident {
                $ident(self)
            }
        }

        impl Manipulable<$ident> for Option<usize> {
            type Return = Option<$ident>;

            fn map(self) -> Option<$ident> {
                self.map(|index| $ident(index))
            }
        }

        impl<E> Manipulable<$ident> for Result<usize, E> {
            type Return = Result<$ident, E>;

            fn map(self) -> Result<$ident, E> {
                self.map(|index| $ident(index))
            }
        }
    )*
    };
}

generate_index!(PositionIdex, ContentIndex, TabIndex);

pub trait Manipulable<T> {
    type Return;
    fn map(self) -> Self::Return;
}