platform-data 2.0.0

Data types and traits for the LinksPlatform
Documentation
/// A structure representing a single value repeated multiple times.
///
/// This is useful for creating queries or representing repeated elements
/// without allocating a vector.
pub struct Point<T> {
    index: T,
    size: usize,
}

impl<T: PartialEq> Point<T> {
    pub const fn new(index: T, size: usize) -> Self {
        Self { index, size }
    }

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

    pub const fn len(&self) -> usize {
        self.size
    }

    pub fn is_full(link: &[T]) -> bool {
        assert!(
            link.len() >= 2,
            "cannot determine link's pointless using only its identifier"
        );

        // SAFETY: slice size is at least 2
        let a = unsafe { link.first().unwrap_unchecked() };
        link.iter().skip(1).all(|b| b == a)
    }

    pub fn is_partial(link: &[T]) -> bool {
        assert!(
            link.len() >= 2,
            "cannot determine link's pointless using only its identifier"
        );

        // SAFETY: slice size is at least 2
        let a = unsafe { link.first().unwrap_unchecked() };
        link.iter().skip(1).any(|b| b == a)
    }

    pub const fn get(&self, index: usize) -> Option<&T> {
        if index < self.len() {
            Some(&self.index)
        } else {
            None
        }
    }
}

/// Iterator for Point that yields copies of the stored value.
pub struct PointIter<T> {
    value: T,
    remaining: usize,
}

impl<T: Copy> Iterator for PointIter<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        if self.remaining > 0 {
            self.remaining -= 1;
            Some(self.value)
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.remaining, Some(self.remaining))
    }
}

impl<T: Copy> ExactSizeIterator for PointIter<T> {}

impl<T: PartialEq + Copy> IntoIterator for Point<T> {
    type Item = T;
    type IntoIter = PointIter<T>;

    fn into_iter(self) -> Self::IntoIter {
        PointIter {
            value: self.index,
            remaining: self.size,
        }
    }
}