Skip to main content

refraction_types/
ring_specialization.rs

1//! Numeric specializations for `BoundedRingBuffer<u8>`.
2//!
3//! This module provides typed enqueue/peek/dequeue helpers that convert values
4//! to and from big-endian bytes.
5//!
6//! # Endianness
7//!
8//! All generated methods use network byte order (big-endian), which makes this
9//! API convenient for protocol frames and wire formats.
10//!
11//! # Example
12//!
13//! ```
14//! use refraction_types::ring_buffer::BoundedRingBuffer;
15//!
16//! let mut rb = BoundedRingBuffer::<u8>::with_capacity(16);
17//! rb.enqueue_u16(0xBEEF);
18//! rb.enqueue_i32(-42);
19//!
20//! assert_eq!(rb.peek_u16(), Some(0xBEEF));
21//! assert_eq!(rb.dequeue_u16(), Some(0xBEEF));
22//! assert_eq!(rb.dequeue_i32(), Some(-42));
23//! ```
24
25use crate::ring_buffer::BoundedRingBuffer;
26
27/// Generates typed enqueue methods for `BoundedRingBuffer<u8>`.
28///
29/// Each generated method encodes the input value into big-endian bytes and
30/// appends those bytes into the buffer.
31macro_rules! impl_enqueue_num {
32    ($( $fn_name:ident: $ty:ty),* $(,)?) => {
33        impl BoundedRingBuffer<u8> {
34            $(
35                pub fn $fn_name(&mut self, value: $ty) {
36                    self.enqueue_slice(&value.to_be_bytes());
37                }
38            )*
39        }
40    };
41}
42
43impl_enqueue_num!(
44    enqueue_u8: u8,
45    enqueue_u16: u16,
46    enqueue_u32: u32,
47    enqueue_u64: u64,
48    enqueue_u128: u128,
49    enqueue_i8: i8,
50    enqueue_i16: i16,
51    enqueue_i32: i32,
52    enqueue_i64: i64,
53    enqueue_i128: i128,
54    enqueue_isize: isize,
55    enqueue_usize: usize,
56    enqueue_f32: f32,
57    enqueue_f64: f64,
58);
59
60/// Generates typed dequeue methods for `BoundedRingBuffer<u8>`.
61///
62/// Each generated method reads `size_of::<T>()` bytes from the buffer and
63/// decodes them from big-endian representation.
64macro_rules! impl_dequeue_num {
65    ($( $fn_name:ident: $ty:ty),* $(,)?) => {
66        impl BoundedRingBuffer<u8> {
67            $(
68                #[must_use]
69                pub fn $fn_name(&mut self) -> Option<$ty> {
70                    const TYPE_SIZE: usize  = size_of::<$ty>();
71                    let mut slice = [0u8; TYPE_SIZE];
72                    if self.dequeue_slice(slice.as_mut_slice(), TYPE_SIZE) != TYPE_SIZE {
73                        return None;
74                    }
75
76                    Some(<$ty>::from_be_bytes(slice))
77                }
78            )*
79        }
80    };
81}
82
83impl_dequeue_num!(
84    dequeue_u8: u8,
85    dequeue_u16: u16,
86    dequeue_u32: u32,
87    dequeue_u64: u64,
88    dequeue_u128: u128,
89    dequeue_i8: i8,
90    dequeue_i16: i16,
91    dequeue_i32: i32,
92    dequeue_i64: i64,
93    dequeue_i128: i128,
94    dequeue_isize: isize,
95    dequeue_usize: usize,
96    dequeue_f32: f32,
97    dequeue_f64: f64,
98);
99
100/// Generates typed peek methods for `BoundedRingBuffer<u8>`.
101///
102/// Each generated method reads from the current front without advancing the
103/// buffer and decodes bytes from big-endian representation.
104macro_rules! impl_pop_num {
105    ($ ($fn_pop_name:ident: $ty:ty),* $(,)? ) => {
106        impl BoundedRingBuffer<u8>
107        {
108            $(
109                #[must_use]
110                pub fn $fn_pop_name(&self) -> Option<$ty> {
111                    const TYPE_SIZE: usize  = size_of::<$ty>();
112
113                    if self.is_empty() || self.len < TYPE_SIZE || self.capacity < TYPE_SIZE {
114                        return None;
115                    }
116
117                    let new_get_idx = (self.get_idx + TYPE_SIZE) % self.capacity;
118                    let mut slice = [0u8; TYPE_SIZE];
119
120                    if new_get_idx < self.get_idx {
121                        let middle = self.capacity - self.get_idx;
122                        slice[..middle].copy_from_slice(&self.data[self.get_idx..]);
123                        slice[middle..].copy_from_slice(&self.data[..new_get_idx]);
124                    } else {
125                        slice.copy_from_slice(&self.data[self.get_idx..new_get_idx]);
126                    }
127
128                    Some(<$ty>::from_be_bytes(slice))
129                }
130            )*
131        }
132    };
133}
134
135impl_pop_num!(
136    peek_u8: u8,
137    peek_u16: u16,
138    peek_u32: u32,
139    peek_u64: u64,
140    peek_u128: u128,
141    peek_i8: i8,
142    peek_i16: i16,
143    peek_i32: i32,
144    peek_i64: i64,
145    peek_i128: i128,
146    peek_usize: usize,
147    peek_isize: isize,
148    peek_f32: f32,
149    peek_f64: f64
150);