1#![cfg_attr(not(feature = "std"), no_std)]
4
5mod allocated;
6pub mod error;
7mod from_u8;
8pub mod funcs;
9mod implements;
10#[cfg(feature = "std")]
11mod macros;
12pub mod max_cap;
13mod primitive;
14
15pub use error::{RapiraError, Result};
16pub use from_u8::{EnumFromU8Error, FromU8};
17#[cfg(feature = "postcard")]
18pub use implements::postcard;
19#[cfg(feature = "zerocopy")]
20pub use implements::zero;
21pub use primitive::{byte_rapira, bytes_rapira, str_rapira};
22
23#[cfg(feature = "alloc")]
24extern crate alloc;
25
26pub use funcs::{
27 check_bytes, deser_unchecked, deser_unsafe, deserialize, deserialize_ctx,
28 deserialize_versioned, size, size_ctx,
29};
30#[cfg(feature = "alloc")]
31pub use funcs::{extend_vec, serialize, serialize_ctx};
32pub use rapira_derive::{FromU8, PrimitiveFromEnum, Rapira};
33
34#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
37pub struct RapiraFlags(pub u64);
38
39impl RapiraFlags {
40 pub const NONE: Self = Self(0);
41
42 #[inline]
43 pub const fn new(flags: u64) -> Self {
44 Self(flags)
45 }
46
47 #[inline]
48 pub const fn has(self, flag: u64) -> bool {
49 self.0 & flag != 0
50 }
51
52 #[inline]
53 pub const fn with(self, flag: u64) -> Self {
54 Self(self.0 | flag)
55 }
56}
57
58pub trait Rapira {
59 const STATIC_SIZE: Option<usize> = None;
60 const MIN_SIZE: usize;
61
62 fn size(&self) -> usize;
64
65 fn check_bytes(slice: &mut &[u8]) -> Result<()>;
67
68 fn from_slice(slice: &mut &[u8]) -> Result<Self>
71 where
72 Self: Sized;
73
74 #[inline]
75 fn debug_from_slice(slice: &mut &[u8]) -> Result<Self>
76 where
77 Self: Sized + std::fmt::Debug,
78 {
79 let len = slice.len();
80 Self::from_slice(slice)
81 .inspect(|item| {
82 println!("len: {len}, item: {item:?}");
83 })
84 .inspect_err(|err| {
85 println!("len: {len}, err: {err:?}");
86 })
87 }
88
89 #[inline]
94 unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
95 where
96 Self: Sized,
97 {
98 Self::from_slice(slice)
99 }
100
101 unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
105 where
106 Self: Sized,
107 {
108 Self::from_slice(slice)
109 }
110
111 #[inline]
159 fn from_slice_versioned(slice: &mut &[u8], _version: u8) -> Result<Self>
160 where
161 Self: Sized,
162 {
163 Self::from_slice(slice)
164 }
165
166 #[inline]
167 fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
168 self.convert_to_bytes(slice, cursor);
169 Ok(())
170 }
171
172 fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize);
173
174 #[inline]
176 fn convert_to_bytes_ctx(&self, slice: &mut [u8], cursor: &mut usize, _flags: RapiraFlags) {
177 self.convert_to_bytes(slice, cursor)
178 }
179
180 #[inline]
182 fn from_slice_ctx(slice: &mut &[u8], _flags: RapiraFlags) -> Result<Self>
183 where
184 Self: Sized,
185 {
186 Self::from_slice(slice)
187 }
188
189 #[inline]
191 fn size_ctx(&self, _flags: RapiraFlags) -> usize {
192 self.size()
193 }
194}
195
196pub const LEN_SIZE: usize = 4;
197
198#[inline]
199pub fn push(slice: &mut [u8], cursor: &mut usize, item: u8) {
200 let s = slice.get_mut(*cursor).unwrap();
201 *s = item;
202 *cursor += 1;
203}
204
205#[inline]
206pub fn try_push(slice: &mut [u8], cursor: &mut usize, item: u8) -> Result<()> {
207 let s = slice.get_mut(*cursor).ok_or(RapiraError::SliceLen)?;
208 *s = item;
209 *cursor += 1;
210
211 Ok(())
212}
213
214#[inline]
215pub fn extend(slice: &mut [u8], cursor: &mut usize, items: &[u8]) {
216 let end = *cursor + items.len();
217 let s = slice.get_mut(*cursor..end).unwrap();
218 s.copy_from_slice(items);
219 *cursor = end;
220}
221
222#[inline]
223pub fn try_extend(slice: &mut [u8], cursor: &mut usize, items: &[u8]) -> Result<()> {
224 let end = *cursor + items.len();
225 let s = slice.get_mut(*cursor..end).ok_or(RapiraError::SliceLen)?;
226 s.copy_from_slice(items);
227 *cursor = end;
228
229 Ok(())
230}
231
232pub const fn static_size<const N: usize>(arr: [Option<usize>; N]) -> Option<usize> {
233 let mut i = 0;
234 let mut size = 0;
235 while i < arr.len() {
236 let item = arr[i];
237 match item {
238 Some(s) => {
239 size += s;
240 }
241 None => {
242 return None;
243 }
244 }
245 i += 1;
246 }
247 Some(size)
248}
249
250pub const fn enum_size<const N: usize>(arr: [Option<usize>; N]) -> Option<usize> {
251 let mut i = 0;
252 let mut size = 0;
253 let mut is_init = false;
254 while i < arr.len() {
255 let item = arr[i];
256 match item {
257 Some(s) => {
258 if !is_init {
259 size = s;
260 is_init = true;
261 } else if s != size {
262 return None;
263 }
264 }
265 None => {
266 return None;
267 }
268 }
269 i += 1;
270 }
271 Some(size + 1)
272}
273
274pub const fn min_size(arr: &'static [usize]) -> usize {
275 let mut i = 0;
276 let mut size = 0;
277 while i < arr.len() {
278 let item = arr[i];
279 size += item;
280 i += 1;
281 }
282 size
283}
284
285pub const fn enum_min_size(arr: &'static [usize]) -> usize {
286 let mut i = 0;
287 let mut size = 0;
288 let mut is_init = false;
289 while i < arr.len() {
290 let item = arr[i];
291 if !is_init {
292 size = item;
293 is_init = true;
294 } else if size < item {
295 size = item;
296 }
297 i += 1;
298 }
299 size + 1
300}