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.
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
staticspecifier can be omitted. -
View The buffer is a non-owning view over externally provided storage. The
viewspecifier is required. -
Alloc The buffer owns heap-allocated storage. The
allocspecifier 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
-
arrayFully initialized fixed-size array ([T; CAP]). Logical length is tracked separately from capacity. -
uninitPartially initialized array ([MaybeUninit<T>; CAP]). Logical length tracks initialized elements and controls drop. -
optionArray of options ([Option<T>; CAP]).Somemarks initialized elements;Nonemarks unused slots.
§View backends
-
slice_mutExclusive slice (&mut [T]). The slice provides backing storage and determines capacity. -
sliceShared slice (&[T]). Read-only view over a contiguous logical range.
§Alloc backends
Requires the alloc crate to be linked:
extern crate alloc;vecGrowableVec<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.