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
//! Numeric specializations for `BoundedRingBuffer<u8>`.
//!
//! This module provides typed enqueue/peek/dequeue helpers that convert values
//! to and from big-endian bytes.
//!
//! # Endianness
//!
//! All generated methods use network byte order (big-endian), which makes this
//! API convenient for protocol frames and wire formats.
//!
//! # Example
//!
//! ```
//! use refraction_types::ring_buffer::BoundedRingBuffer;
//!
//! let mut rb = BoundedRingBuffer::<u8>::with_capacity(16);
//! rb.enqueue_u16(0xBEEF);
//! rb.enqueue_i32(-42);
//!
//! assert_eq!(rb.peek_u16(), Some(0xBEEF));
//! assert_eq!(rb.dequeue_u16(), Some(0xBEEF));
//! assert_eq!(rb.dequeue_i32(), Some(-42));
//! ```

use crate::ring_buffer::BoundedRingBuffer;

/// Generates typed enqueue methods for `BoundedRingBuffer<u8>`.
///
/// Each generated method encodes the input value into big-endian bytes and
/// appends those bytes into the buffer.
macro_rules! impl_enqueue_num {
    ($( $fn_name:ident: $ty:ty),* $(,)?) => {
        impl BoundedRingBuffer<u8> {
            $(
                pub fn $fn_name(&mut self, value: $ty) {
                    self.enqueue_slice(&value.to_be_bytes());
                }
            )*
        }
    };
}

impl_enqueue_num!(
    enqueue_u8: u8,
    enqueue_u16: u16,
    enqueue_u32: u32,
    enqueue_u64: u64,
    enqueue_u128: u128,
    enqueue_i8: i8,
    enqueue_i16: i16,
    enqueue_i32: i32,
    enqueue_i64: i64,
    enqueue_i128: i128,
    enqueue_isize: isize,
    enqueue_usize: usize,
    enqueue_f32: f32,
    enqueue_f64: f64,
);

/// Generates typed dequeue methods for `BoundedRingBuffer<u8>`.
///
/// Each generated method reads `size_of::<T>()` bytes from the buffer and
/// decodes them from big-endian representation.
macro_rules! impl_dequeue_num {
    ($( $fn_name:ident: $ty:ty),* $(,)?) => {
        impl BoundedRingBuffer<u8> {
            $(
                #[must_use]
                pub fn $fn_name(&mut self) -> Option<$ty> {
                    const TYPE_SIZE: usize  = size_of::<$ty>();
                    let mut slice = [0u8; TYPE_SIZE];
                    if self.dequeue_slice(slice.as_mut_slice(), TYPE_SIZE) != TYPE_SIZE {
                        return None;
                    }

                    Some(<$ty>::from_be_bytes(slice))
                }
            )*
        }
    };
}

impl_dequeue_num!(
    dequeue_u8: u8,
    dequeue_u16: u16,
    dequeue_u32: u32,
    dequeue_u64: u64,
    dequeue_u128: u128,
    dequeue_i8: i8,
    dequeue_i16: i16,
    dequeue_i32: i32,
    dequeue_i64: i64,
    dequeue_i128: i128,
    dequeue_isize: isize,
    dequeue_usize: usize,
    dequeue_f32: f32,
    dequeue_f64: f64,
);

/// Generates typed peek methods for `BoundedRingBuffer<u8>`.
///
/// Each generated method reads from the current front without advancing the
/// buffer and decodes bytes from big-endian representation.
macro_rules! impl_pop_num {
    ($ ($fn_pop_name:ident: $ty:ty),* $(,)? ) => {
        impl BoundedRingBuffer<u8>
        {
            $(
                #[must_use]
                pub fn $fn_pop_name(&self) -> Option<$ty> {
                    const TYPE_SIZE: usize  = size_of::<$ty>();

                    if self.is_empty() || self.len < TYPE_SIZE || self.capacity < TYPE_SIZE {
                        return None;
                    }

                    let new_get_idx = (self.get_idx + TYPE_SIZE) % self.capacity;
                    let mut slice = [0u8; TYPE_SIZE];

                    if new_get_idx < self.get_idx {
                        let middle = self.capacity - self.get_idx;
                        slice[..middle].copy_from_slice(&self.data[self.get_idx..]);
                        slice[middle..].copy_from_slice(&self.data[..new_get_idx]);
                    } else {
                        slice.copy_from_slice(&self.data[self.get_idx..new_get_idx]);
                    }

                    Some(<$ty>::from_be_bytes(slice))
                }
            )*
        }
    };
}

impl_pop_num!(
    peek_u8: u8,
    peek_u16: u16,
    peek_u32: u32,
    peek_u64: u64,
    peek_u128: u128,
    peek_i8: i8,
    peek_i16: i16,
    peek_i32: i32,
    peek_i64: i64,
    peek_i128: i128,
    peek_usize: usize,
    peek_isize: isize,
    peek_f32: f32,
    peek_f64: f64
);