osom_lib_arrays/fixed_array/
const_buffer.rs1#![allow(
2 clippy::cast_possible_wrap,
3 clippy::cast_sign_loss,
4 clippy::cast_possible_truncation,
5 clippy::needless_return,
6 clippy::new_without_default
7)]
8
9use crate::const_helpers::subslice_const;
10
11use super::ConstFixedArray;
12
13use osom_lib_primitives::length::Length;
14use osom_lib_reprc::traits::ReprC;
15
16#[repr(transparent)]
51#[must_use]
52pub struct ConstBuffer<const TSIZE: usize, T: Sized + Copy> {
53 array: ConstFixedArray<TSIZE, T>,
54}
55
56unsafe impl<const TSIZE: usize, T: ReprC + Sized + Copy> ReprC for ConstBuffer<TSIZE, T> {
57 const CHECK: () = {
58 let () = <ConstFixedArray<TSIZE, T> as ReprC>::CHECK;
59 };
60}
61
62impl<const TSIZE: usize, T: Sized + Copy> ConstBuffer<TSIZE, T> {
63 #[inline(always)]
65 pub const fn new() -> Self {
66 Self {
67 array: ConstFixedArray::new(),
68 }
69 }
70
71 #[inline(always)]
77 pub const fn buffer_const<'a>(&'a mut self, data: &'a [T]) -> ConstBufferer<'a, TSIZE, T> {
78 assert!(data.len() <= u32::MAX as usize, "Data length cannot exceed u32::MAX");
79 ConstBufferer::new(&mut self.array, data)
80 }
81
82 #[inline(always)]
84 pub const fn length(&self) -> Length {
85 self.array.length()
86 }
87
88 #[inline(always)]
90 pub const fn clone_const(&self) -> Self {
91 Self {
92 array: self.array.clone_const(),
93 }
94 }
95
96 #[inline(always)]
98 pub const fn current_state_const(&self) -> &ConstFixedArray<TSIZE, T> {
99 &self.array
100 }
101
102 #[inline(always)]
104 pub const fn release_const(self) -> ConstFixedArray<TSIZE, T> {
105 let mut array = self.array;
106 if array.length().as_usize() == TSIZE {
107 array.drain();
108 }
109 array
110 }
111}
112
113#[repr(C)]
115#[must_use]
116pub struct ConstBufferer<'a, const TSIZE: usize, T: Sized + Copy + 'a> {
117 array: &'a mut ConstFixedArray<TSIZE, T>,
118 data: &'a [T],
119 data_offset: i64,
120}
121
122unsafe impl<const TSIZE: usize, T: ReprC + Sized + Copy> ReprC for ConstBufferer<'_, TSIZE, T> {
123 const CHECK: () = ();
124}
125
126impl<'a, const TSIZE: usize, T: Sized + Copy> ConstBufferer<'a, TSIZE, T> {
127 #[inline(always)]
128 const fn new(array: &'a mut ConstFixedArray<TSIZE, T>, data: &'a [T]) -> Self {
129 Self {
130 array,
131 data,
132 data_offset: 0,
133 }
134 }
135
136 pub const fn next(&mut self) -> Option<&[T; TSIZE]> {
138 if self.data_offset as usize == self.data.len() {
139 return None;
140 }
141
142 unsafe {
143 let real_slice = subslice_const(self.data, self.data_offset as usize..self.data.len());
144 let real_len = real_slice.len() as u32;
145
146 if self.array.length().as_usize() == TSIZE {
147 self.array.drain();
148 }
149
150 let len = self.array.length().as_usize();
151
152 if (real_len as u64) + len as u64 >= TSIZE as u64 {
153 let missing = TSIZE - len;
154 let subslice = subslice_const(real_slice, 0..missing);
155 self.array.push_slice_const(subslice);
156 self.data_offset += missing as i64;
157 debug_assert!(self.array.length().as_usize() == TSIZE);
158 return Some(self.array.as_raw_slice_const());
159 }
160
161 self.array.push_slice_const(real_slice);
162 self.data_offset += real_len as i64;
163 debug_assert!(self.array.length().as_usize() < TSIZE);
164 return None;
165 }
166 }
167}