multilinear-parser 0.5.1

A parser for the multilinear story systems
Documentation
use std::{
    marker::PhantomData,
    ops::{Index, IndexMut},
};

/// Stores index based maps.
pub struct IndexMap<I: Into<usize> + From<usize>, V> {
    pub(crate) entries: Vec<V>,
    index: PhantomData<I>,
}

impl<I: Into<usize> + From<usize>, V> Default for IndexMap<I, V> {
    fn default() -> Self {
        Self {
            entries: Vec::new(),
            index: PhantomData,
        }
    }
}

impl<I: Into<usize> + From<usize>, V> IndexMap<I, V> {
    /// Returns if the index map contains no elements.
    pub fn is_empty(&self) -> bool {
        self.entries.is_empty()
    }

    /// Returns the number of elements.
    pub fn len(&self) -> usize {
        self.entries.len()
    }

    /// Gets an entry by index.
    pub fn get(&self, index: I) -> Option<&V> {
        self.entries.get(index.into())
    }

    /// Gets a mutable entry by index.
    pub fn get_mut(&self, index: I) -> Option<&V> {
        self.entries.get(index.into())
    }

    /// Returns an iterator over the index map.
    pub fn iter(&self) -> Iter<'_, I, V> {
        self.into_iter()
    }

    pub(crate) fn insert(&mut self, index: I, value: V) {
        let i = index.into();
        assert_eq!(i, self.entries.len(), "Wrong insertion order");
        self.entries.push(value);
    }
}

impl<I: Into<usize> + From<usize>, V> Index<I> for IndexMap<I, V> {
    type Output = V;

    fn index(&self, index: I) -> &V {
        &self.entries[index.into()]
    }
}

impl<I: Into<usize> + From<usize>, V> IndexMut<I> for IndexMap<I, V> {
    fn index_mut(&mut self, index: I) -> &mut V {
        &mut self.entries[index.into()]
    }
}

/// An iterator over indices and values of an index map.
pub struct IntoIter<I: Into<usize> + From<usize>, V> {
    data: std::iter::Enumerate<std::vec::IntoIter<V>>,
    index: PhantomData<I>,
}

impl<I: Into<usize> + From<usize>, V> Iterator for IntoIter<I, V> {
    type Item = (I, V);

    fn next(&mut self) -> Option<(I, V)> {
        let (i, value) = self.data.next()?;
        Some((i.into(), value))
    }
}

impl<I: Into<usize> + From<usize>, V> IntoIterator for IndexMap<I, V> {
    type Item = (I, V);
    type IntoIter = IntoIter<I, V>;

    fn into_iter(self) -> IntoIter<I, V> {
        IntoIter {
            data: self.entries.into_iter().enumerate(),
            index: PhantomData,
        }
    }
}

/// An iterator over indices and values of an index map as references.
pub struct Iter<'a, I: Into<usize> + From<usize>, V> {
    data: std::iter::Enumerate<std::slice::Iter<'a, V>>,
    index: PhantomData<I>,
}

impl<'a, I: Into<usize> + From<usize>, V> Iterator for Iter<'a, I, V> {
    type Item = (I, &'a V);

    fn next(&mut self) -> Option<(I, &'a V)> {
        let (i, value) = self.data.next()?;
        Some((i.into(), value))
    }
}

impl<'a, I: Into<usize> + From<usize>, V> IntoIterator for &'a IndexMap<I, V> {
    type Item = (I, &'a V);
    type IntoIter = Iter<'a, I, V>;

    fn into_iter(self) -> Iter<'a, I, V> {
        Iter {
            data: self.entries.iter().enumerate(),
            index: PhantomData,
        }
    }
}