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::{check_bytes, deser_unchecked, deser_unsafe, deserialize, size};
27#[cfg(feature = "alloc")]
28pub use funcs::{extend_vec, serialize};
29pub use rapira_derive::{FromU8, PrimitiveFromEnum, Rapira};
30
31pub trait Rapira {
32 const STATIC_SIZE: Option<usize> = None;
33 const MIN_SIZE: usize;
34
35 fn size(&self) -> usize;
37
38 fn check_bytes(slice: &mut &[u8]) -> Result<()>;
40
41 fn from_slice(slice: &mut &[u8]) -> Result<Self>
44 where
45 Self: Sized;
46
47 #[inline]
48 fn debug_from_slice(slice: &mut &[u8]) -> Result<Self>
49 where
50 Self: Sized + std::fmt::Debug,
51 {
52 let len = slice.len();
53 Self::from_slice(slice)
54 .inspect(|item| {
55 println!("len: {len}, item: {item:?}");
56 })
57 .inspect_err(|err| {
58 println!("len: {len}, err: {err:?}");
59 })
60 }
61
62 #[inline]
67 unsafe fn from_slice_unchecked(slice: &mut &[u8]) -> Result<Self>
68 where
69 Self: Sized,
70 {
71 Self::from_slice(slice)
72 }
73
74 unsafe fn from_slice_unsafe(slice: &mut &[u8]) -> Result<Self>
78 where
79 Self: Sized,
80 {
81 Self::from_slice(slice)
82 }
83
84 #[inline]
85 fn try_convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) -> Result<()> {
86 self.convert_to_bytes(slice, cursor);
87 Ok(())
88 }
89
90 fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize);
91}
92
93pub const LEN_SIZE: usize = 4;
94
95#[inline]
96pub fn push(slice: &mut [u8], cursor: &mut usize, item: u8) {
97 let s = slice.get_mut(*cursor).unwrap();
98 *s = item;
99 *cursor += 1;
100}
101
102#[inline]
103pub fn try_push(slice: &mut [u8], cursor: &mut usize, item: u8) -> Result<()> {
104 let s = slice.get_mut(*cursor).ok_or(RapiraError::SliceLen)?;
105 *s = item;
106 *cursor += 1;
107
108 Ok(())
109}
110
111#[inline]
112pub fn extend(slice: &mut [u8], cursor: &mut usize, items: &[u8]) {
113 let end = *cursor + items.len();
114 let s = slice.get_mut(*cursor..end).unwrap();
115 s.copy_from_slice(items);
116 *cursor = end;
117}
118
119#[inline]
120pub fn try_extend(slice: &mut [u8], cursor: &mut usize, items: &[u8]) -> Result<()> {
121 let end = *cursor + items.len();
122 let s = slice.get_mut(*cursor..end).ok_or(RapiraError::SliceLen)?;
123 s.copy_from_slice(items);
124 *cursor = end;
125
126 Ok(())
127}
128
129pub const fn static_size<const N: usize>(arr: [Option<usize>; N]) -> Option<usize> {
130 let mut i = 0;
131 let mut size = 0;
132 while i < arr.len() {
133 let item = arr[i];
134 match item {
135 Some(s) => {
136 size += s;
137 }
138 None => {
139 return None;
140 }
141 }
142 i += 1;
143 }
144 Some(size)
145}
146
147pub const fn enum_size<const N: usize>(arr: [Option<usize>; N]) -> Option<usize> {
148 let mut i = 0;
149 let mut size = 0;
150 let mut is_init = false;
151 while i < arr.len() {
152 let item = arr[i];
153 match item {
154 Some(s) => {
155 if !is_init {
156 size = s;
157 is_init = true;
158 } else if s != size {
159 return None;
160 }
161 }
162 None => {
163 return None;
164 }
165 }
166 i += 1;
167 }
168 Some(size + 1)
169}
170
171pub const fn min_size(arr: &'static [usize]) -> usize {
172 let mut i = 0;
173 let mut size = 0;
174 while i < arr.len() {
175 let item = arr[i];
176 size += item;
177 i += 1;
178 }
179 size
180}
181
182pub const fn enum_min_size(arr: &'static [usize]) -> usize {
183 let mut i = 0;
184 let mut size = 0;
185 let mut is_init = false;
186 while i < arr.len() {
187 let item = arr[i];
188 if !is_init {
189 size = item;
190 is_init = true;
191 } else if size < item {
192 size = item;
193 }
194 i += 1;
195 }
196 size + 1
197}