Skip to main content

buffer_linear

Macro buffer_linear 

Source
macro_rules! buffer_linear {
    (
    // STATIC (array, uninit, option)
    // struct definition + optional implementations

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

        $(#[$attr:meta])*                                        // attributes
        $vis:vis struct $name:ident : view ($($I:tt)+);          // visibility, name, index type
        $($rest:tt)*                                             // impls
    ) => { ... };
    ( // implementations only
        impl $name:ident : view ($($I:tt)+) ; $($rest:tt)*       // for name, index type, impls
    ) => { ... };
    (
    // ALLOC (vec)
    // struct definition + optional implementations

        $(#[$attr:meta])*                                        // attributes
        $vis:vis struct $name:ident : alloc ($($I:tt)+);         // visibility, name, index type
        $($rest:tt)*                                             // impls
    ) => { ... };
    ( // implementations only
        impl $name:ident : alloc ($($I:tt)+) ; $($rest:tt)*      // for name, index type, impls
    ) => { ... };
    (

    /* 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])* uninit , $($rest:tt)*) => { ... };
    (%impl1_static $(#[$i:meta])* $name:ident : $I:ty, $P:ty; uninit) => { ... };
    (%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_view $name:ident : $I:ty, $P:ty ;) => { ... };
    (%impls_view $name:ident : $I:ty, $P:ty ; $(#[$i:meta])* $impl:ident) => { ... };
    (%impls_view $name:ident : $I:ty, $P:ty ; $(#[$i:meta])* slice_mut , $($rest:tt)*) => { ... };
    (%impl1_view $(#[$i:meta])* $name:ident : $I:ty, $P:ty ; slice_mut) => { ... };
    (%impls_view $name:ident : $I:ty, $P:ty ; $(#[$i:meta])* slice , $($rest:tt)*) => { ... };
    (%impl1_view $(#[$i:meta])* $name:ident : $I:ty, $P:ty ; slice) => { ... };
    (%impls_alloc $name:ident : $I:ty, $P:ty ;) => { ... };
    (%impls_alloc $name:ident : $I:ty, $P:ty ; $(#[$i:meta])* $impl:ident) => { ... };
    (%impls_alloc $name:ident : $I:ty, $P:ty ; $(#[$i:meta])* vec , $($rest:tt)*) => { ... };
    (%impl1_alloc $(#[$i:meta])* $name:ident : $I:ty, $P:ty; vec) => { ... };
    (%impls_static $name:ident : $_I:ty, $_P:ty ; $(#[$_i:meta])* $impl:ident , $($_r:tt)*) => { ... };
    (%impls_view $name:ident : $_I:ty, $_P:ty ; $(#[$_i:meta])* $impl:ident , $($_r:tt)*) => { ... };
    (%impls_alloc $name:ident : $_I:ty, $_P:ty ; $(#[$_i:meta])* $impl:ident , $($_r:tt)*) => { ... };
    (%impl_common_static $name:ident, $I:ty, $P:ty) => { ... };
    (%impl_common_view $name:ident, $I:ty, $P:ty) => { ... };
    (%impl_common_alloc $name:ident, $I:ty, $P:ty) => { ... };
    (%common_tracked $name:ident, $I:ty, $P:ty) => { ... };
    (%common_delegated $name:ident, $I:ty, $P:ty) => { ... };
    (%common_static $name:ident, $I:ty, $P:ty) => { ... };
    (%common_view $name:ident, $I:ty, $P:ty) => { ... };
    (%common_iter_visit $name:ident, $I:ty, $P:ty) => { ... };
    (%guard_index_repr $I:ty) => { ... };
}
Expand description

🏗️ 🗃️ Defines a linear buffer type over contiguous storage backends.


📍 data/layout::buffer_linear


The generated type represents a logical range over contiguous storage, using an index type to track length and bounds.

§Ownership regimes

The macro supports three regimes:

  • static (default) The buffer owns its fixed-capacity storage backend. The optional static specifier can be omitted.

  • View The buffer is a non-owning view over externally provided storage. The view specifier is required.

  • Alloc The buffer owns heap-allocated storage. The alloc specifier is required.

§Index type requirements

The index type must:

  • Be non-negative
  • Represent zero
  • Form a contiguous integer range
  • Be able to represent all valid buffer positions

Primitive unsigned integers and supported niche wrappers are accepted (see MaybeNiche).

§Storage backends

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

§Fixed-capacity backends

  • array Fully initialized fixed-size array ([T; CAP]). Logical length is tracked separately from capacity.

  • uninit Partially initialized array ([MaybeUninit<T>; CAP]). Logical length tracks initialized elements and controls drop.

  • option Array of options ([Option<T>; CAP]). Some marks initialized elements; None marks unused slots.

§View backends

  • slice_mut Exclusive slice (&mut [T]). The slice provides backing storage and determines capacity.

  • slice Shared slice (&[T]). Read-only view over a contiguous logical range.

§Alloc backends

Requires the alloc crate to be linked:

extern crate alloc;
  • vec Growable Vec<T> storage.

Only explicitly enabled backends generate implementations. Constructors and methods depend on the selected backends.

§Examples

§Static buffer (default)

use devela::buffer_linear;

buffer_linear!(
    /// Static linear buffer.
    pub struct BufferU8: (u8); array
);
let mut buf = BufferU8::<i32, [i32; 8]>::new_init();
buf.push_back(10).unwrap();
buf.push_back(20).unwrap();
assert_eq!(buf.as_slice(), &[10, 20]);

§View buffer

use devela::buffer_linear;

buffer_linear!(
    /// Read-only linear view.
    pub struct BufferViewU8: view (u8); slice
);
let storage = [1u8, 2, 3, 4];
let buf = BufferViewU8::try_from_slice(&storage).unwrap();
assert_eq!(buf.len_prim(), 4);
assert_eq!(buf.peek_back(), Some(&4));

§Alloc buffer

use devela::buffer_linear;

buffer_linear!(
    /// Dynamic linear buffer.
    pub struct BufferU8: alloc (u8); vec
);
let mut buf = BufferU8::new();
buf.push_back(10);
buf.push_back(20);
assert_eq!(buf.as_slice(), &[10, 20]);

§Separate implementation blocks

use devela::buffer_linear;

buffer_linear!(pub struct BufferSplit: view (u8););
buffer_linear!(impl BufferSplit: view (u8); slice, slice_mut);

See also: BufferLinearStaticExample, BufferLinearViewExample, BufferLinearAllocExample.