sigmut 0.0.2

a state management framework designed to be used as a foundation for UI frameworks.
Documentation
use std::{
    cmp::{max, min},
    collections::VecDeque,
    ops::{Index, IndexMut},
};

#[derive(Debug)]
pub struct ISizeMap<T> {
    start: isize,
    values: VecDeque<T>,
    default: T,
}

impl<T: Default> ISizeMap<T> {
    pub fn new() -> Self {
        Self {
            start: 0,
            values: VecDeque::new(),
            default: T::default(),
        }
    }
    pub fn len(&self) -> usize {
        self.values.len()
    }
    pub fn is_empty(&self) -> bool {
        self.values.is_empty()
    }
    pub fn end_index(&self) -> isize {
        self.start + self.values.len() as isize
    }
    pub fn get_mut(&mut self, index: isize) -> Option<&mut T> {
        if self.start <= index && (index - self.start) < self.values.len() as isize {
            Some(&mut self.values[(index - self.start) as usize])
        } else {
            None
        }
    }

    fn prepare(&mut self, start: isize, last: isize) {
        assert!(start <= last);
        if self.is_empty() {
            self.start = start;
            self.values.reserve((last + 1 - start) as usize);
            self.values.push_back(T::default());
        } else {
            let end = self.end_index();
            let len = self.len();
            let len_new = (max(last + 1, end) - min(self.start, start)) as usize;
            if len_new > len {
                self.values.reserve(len_new - len);
            }
        }
        while start < self.start {
            self.values.push_front(T::default());
            self.start -= 1;
        }
        while self.values.len() <= (last - self.start) as usize {
            self.values.push_back(T::default());
        }
    }
}
impl<T: Default> Index<isize> for ISizeMap<T> {
    type Output = T;
    fn index(&self, index: isize) -> &Self::Output {
        if self.start <= index && (index - self.start) < self.values.len() as isize {
            &self.values[(index - self.start) as usize]
        } else {
            &self.default
        }
    }
}
impl<T: Default> IndexMut<isize> for ISizeMap<T> {
    fn index_mut(&mut self, index: isize) -> &mut Self::Output {
        self.prepare(index, index);
        self.get_mut(index).unwrap()
    }
}