bufferring 0.0.2

Ring buffers for Rust
Documentation
use core::fmt::{self, Debug};
use core::mem::MaybeUninit;
use core::pin::Pin;

use super::{Slot, Storage};

/// Storage for ring buffers in a fixed-size array.
///
/// The underlying data is stored inline in this structure, and it has a fixed
/// (non-zero) size that must be selected at compile-time.
pub struct ArrayStorage<T, const N: usize> {
    /// The underlying data.
    data: [Slot<T>; N],
}

impl<T, const N: usize> ArrayStorage<T, N> {
    /// A compile-time assertion that the capacity must not be zero.
    const CAPACITY_IS_NONZERO: () =
        assert!(N != 0, "Ring buffers require a non-zero capacity!");

    /// Create a new [`ArrayStorage`].
    pub fn new() -> Self {
        // NOTE: By referencing this value, the compile-time check is executed.
        let _ = Self::CAPACITY_IS_NONZERO;

        // SAFETY: [`Slot`] does not require initialization.
        Self { data: unsafe { MaybeUninit::uninit().assume_init() } }
    }
}

// SAFETY:
// - The same slice is returned by get(), get_mut(), and get_pin().
// - There is no way to modify the slice externally.
unsafe impl<T, const N: usize> Storage for ArrayStorage<T, N> {
    type Item = T;

    fn cap(&self) -> usize {
        N
    }

    fn get(&self) -> &[Slot<Self::Item>] {
        &self.data
    }

    fn get_mut(&mut self) -> &mut [Slot<Self::Item>] {
        &mut self.data
    }

    fn get_pin(self: Pin<&mut Self>) -> Pin<&mut [Slot<Self::Item>]> {
        // NOTE: We could use the pin-project crate, but there's no need for a
        // new dependency when we already have 'unsafe' code all over.

        // SAFETY: The slice is a pinned part of the object.
        unsafe { self.map_unchecked_mut(|this| &mut this.data) }
    }
}

impl<T, const N: usize> Clone for ArrayStorage<T, N> {
    fn clone(&self) -> Self {
        Self::new()
    }
}

impl<T, const N: usize> Debug for ArrayStorage<T, N> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "ArrayStorage")
    }
}