Skip to main content

buffer_ring

Macro buffer_ring 

Source
macro_rules! buffer_ring {
    (
    // STATIC (option)
    // struct definition + optional implementations

        $(#[$attr:meta])*
        $vis:vis struct $name:ident : $(static)? ($($I:tt)+);
        $($rest:tt)*
    ) => { ... };
    ( // implementations only
        impl $name:ident : $(static)? ($($I:tt)+); $($rest:tt)*
    ) => { ... };
    (
    // VIEW:  TODO: (slice_mut, slice)
    // struct definition + optional implementations

        $(#[$_attr:meta])*
        $_vis:vis struct $_name:ident : view ($($_I:tt)+);
        $($_rest:tt)*
    ) => { ... };
    ( // implementations only
        impl $_name:ident : view ($($_I:tt)+);
        $($_rest:tt)*
    ) => { ... };
    (
    // ALLOC TODO: (vec)
    // struct definition + optional implementations

        $(#[$_attr:meta])*
        $_vis:vis struct $_name:ident : alloc ($($_I:tt)+);
        $($_rest:tt)*
    ) => { ... };
    ( // implementations only
        impl $_name:ident : alloc ($($_I:tt)+);
        $($_rest:tt)*
    ) => { ... };
    (

    /* internals */
    %impls_static $name:ident : $I:ty, $P:ty ;) => { ... };
    (%impls_static $name:ident : $I:ty, $P:ty ; $(#[$i:meta])* $impl:ident) => { ... };
    (%impls_static $name:ident : $I:ty, $P:ty ; $(#[$i:meta])* array , $($rest:tt)*) => { ... };
    (%impl1_static $(#[$i:meta])* $name:ident : $I:ty, $P:ty ; array) => { ... };
    (%impls_static $name:ident : $I:ty, $P:ty ; $(#[$i:meta])* option , $($rest:tt)*) => { ... };
    (%impl1_static $(#[$i:meta])* $name:ident : $I:ty, $P:ty ; option) => { ... };
    (%impls_static $_name:ident : $_I:ty, $_P:ty ; $(#[$_i:meta])* $impl:ident , $($_r:tt)*) => { ... };
    (%impl1_static $(#[$_i:meta])* $_name:ident : $_I:ty, $_P:ty ; $impl:ident) => { ... };
    (%impl_common_static $name:ident, $I:ty, $P:ty) => { ... };
    (%common_tracked $name:ident, $I:ty, $P:ty) => { ... };
    (%common_static $name:ident, $I:ty, $P:ty) => { ... };
    (%guard_index_repr $I:ty) => { ... };
}
Expand description

๐Ÿ—๏ธ ๐Ÿ—ƒ๏ธ Defines a ring buffer type over contiguous storage backends.


๐Ÿ“ data/layout::buffer_ring


The generated type represents a fixed-capacity circular logical range over contiguous storage.

A ring tracks:

  • head: the physical start of the logical range.
  • len: the number of live elements.

The tail is not stored. It is derived as (head + len) % capacity.

ยงImplemented backends

Currently implemented:

  • static array Fully initialized array storage ([T; CAP]). All slots always contain a valid T; len controls which slots are logically visible.
  • static option Array of options ([Option<T>; CAP]). Occupied logical slots are Some; unused physical slots are None.

Reserved for later:

  • static uninit
  • view backends
  • alloc backends

ยงIndex type requirements

The index type must:

  • Be non-negative.
  • Represent zero.
  • Form a contiguous integer range.
  • Be able to represent the full capacity.

Primitive unsigned integers and supported niche wrappers are accepted through MaybeNiche.

ยงStorage backends

Backends are opt-in and selected after the struct declaration.

  • array Fully initialized array storage ([T; CAP]).

    This backend separates initialization from logical membership: every physical slot stores a valid T, while len determines which elements are visible through the ring API.

    Operations that move values out of the array require either:

    • copying (*_copy),
    • an explicit replacement (*_with),
    • or a convenience replacement (*_default, *_init).
  • option Array of options ([Option<T>; CAP]).

    This backend stores occupancy explicitly: occupied logical slots are Some(T), and unused physical slots are None.

    It supports moving arbitrary T values in and out without requiring replacement values.

ยงExamples

use devela::buffer_ring;

buffer_ring!(
    /// Static ring buffer.
    pub struct RingU8: (u8);
    array, option
);

let mut array_ring = RingU8::<i32, [i32; 4]>::new_init();
array_ring.push_back(10).unwrap();
array_ring.push_back(20).unwrap();

assert_eq!(array_ring.pop_front_copy(), Some(10));
assert_eq!(array_ring.peek_front(), Some(&20));

let mut option_ring = RingU8::<i32, [Option<i32>; 4]>::new_empty();
option_ring.push_back(10).unwrap();
option_ring.push_back(20).unwrap();

assert_eq!(option_ring.pop_front(), Some(10));
assert_eq!(option_ring.peek_front(), Some(&20));

See also: BufferRingStaticExample,