refraction-types 0.1.1

Zero-dependency bounded ring buffer for networking workloads with predictable overwrite-on-full semantics, minimal allocations, and an ergonomic byte-oriented API.
Documentation
use crate::ring_buffer::BoundedRingBuffer;

impl<T> Default for BoundedRingBuffer<T>
where
    T: Copy + Default,
{
    fn default() -> Self {
        Self::new()
    }
}

impl<T> std::fmt::Display for BoundedRingBuffer<T>
where
    T: std::fmt::Display,
{
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(f, "BoundedRingBuffer {{")?;
        #[allow(clippy::cast_precision_loss)]
        writeln!(
            f,
            "    len: {} / {} ({:.1}% full)",
            self.len,
            self.capacity,
            if self.capacity == 0 {
                0.0
            } else {
                (self.len as f64 / self.capacity as f64) * 100.0
            }
        )?;
        writeln!(
            f,
            "    get_idx: {}, put_idx: {}",
            self.get_idx, self.put_idx
        )?;

        write!(f, "    data: [")?;
        let mut idx = self.get_idx;
        for i in 0..self.len {
            if i > 0 {
                write!(f, ", ")?;
            }
            write!(f, "{}", self.data[idx])?;
            idx = (idx + 1) % self.capacity;
        }
        writeln!(f, "]")?;

        write!(f, "}}")
    }
}

//EXTEND
impl<T> Extend<T> for BoundedRingBuffer<T>
where
    T: Copy + Default,
{
    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
        //maybe we can optimize it
        for item in iter {
            self.enqueue(item);
        }
    }
}

//FROM
impl<T> FromIterator<T> for BoundedRingBuffer<T>
where
    T: Copy + Default,
{
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
        let items: Vec<T> = iter.into_iter().collect();
        let mut buffer = Self::with_capacity(items.len().max(1));
        buffer.enqueue_slice(&items);
        buffer
    }
}

impl<T> From<&[T]> for BoundedRingBuffer<T>
where
    T: Copy + Default,
{
    fn from(slice: &[T]) -> Self {
        let mut buffer = Self::with_capacity(slice.len().max(1));
        buffer.enqueue_slice(slice);
        buffer
    }
}

impl<T> From<Vec<T>> for BoundedRingBuffer<T>
where
    T: Copy + Default,
{
    fn from(vec: Vec<T>) -> Self {
        Self::from(vec.as_slice())
    }
}