1#![cfg_attr(not(feature="std"), no_std)]
2
3#![doc = include_str!("../README.md")]
4
5extern crate alloc;
6
7pub mod rw;
8pub mod numeric;
9
10use bounded_static::{IntoBoundedStatic, ToBoundedStatic};
11pub use rw::*;
12pub use numeric::*;
13
14use core::{ops::{Deref, DerefMut}, result::Result, mem::MaybeUninit, marker::PhantomData, borrow::Borrow};
15
16use alloc::{string::String, borrow::Cow, borrow::ToOwned, vec::Vec};
17
18pub use binmarshal_macros::{Marshal, Demarshal, MarshalUpdate, Proxy};
19
20#[derive(Debug, Clone, PartialEq, Eq)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
23pub enum MarshalError {
24 BufferTooSmall,
25 IllegalValue {
26 byte_offset: usize,
27 bit_offset: usize,
28 },
29 IllegalTag,
30 CoercionError,
31 ExpectedSentinel,
32}
33
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub struct BitSpecification<const BITS: usize>;
36
37pub trait Marshal<Context = ()> {
38 fn write<W: BitWriter>(&self, writer: &mut W, ctx: Context) -> Result<(), MarshalError>;
39}
40
41pub trait Demarshal<'dm, Context = ()> : Sized {
42 fn read(view: &mut BitView<'dm>, ctx: Context) -> Result<Self, MarshalError>;
43}
44
45impl<'a, C, T: Marshal<C> + ?Sized> Marshal<C> for &'a T {
46 fn write<W: BitWriter>(&self, writer: &mut W, ctx: C) -> Result<(), MarshalError> {
47 (self as &'a T).write(writer, ctx)
48 }
49}
50pub trait DemarshalOwned<Context = ()> : for<'de> Demarshal<'de, Context> {}
52impl<T, Context> DemarshalOwned<Context> for T where T: for<'de> Demarshal<'de, Context> {}
53
54pub trait MarshalUpdate<Context = ()> : Sized {
55 fn update(&mut self, ctx: &mut Context);
56}
57
58impl Marshal<()> for () {
59 #[inline(always)]
60 fn write<W: BitWriter>(&self, _writer: &mut W, _ctx: ()) -> Result<(), MarshalError> {
61 Ok(())
62 }
63}
64
65impl<'dm> Demarshal<'dm, ()> for () {
66 #[inline(always)]
67 fn read(_view: &mut BitView<'dm>, _ctx: ()) -> Result<Self, MarshalError> {
68 Ok(())
69 }
70}
71
72impl<C: Clone, T: Marshal<C>, const N: usize> Marshal<C> for [T; N] {
73 #[inline]
74 fn write<W: BitWriter>(&self, writer: &mut W, ctx: C) -> Result<(), MarshalError> {
75 for v in self.iter() {
76 v.write(writer, ctx.clone())?;
77 }
78 Ok(())
79 }
80}
81
82impl<'dm, C: Clone, T: Demarshal<'dm, C>, const N: usize> Demarshal<'dm, C> for [T; N] {
83 fn read(view: &mut BitView<'dm>, ctx: C) -> Result<Self, MarshalError> {
84 let mut arr: [MaybeUninit<T>; N] = unsafe { MaybeUninit::uninit().assume_init() };
85 for i in 0..N {
86 arr[i] = MaybeUninit::new(T::read(view, ctx.clone())?);
87 }
88 return unsafe { Ok(arr.as_ptr().cast::<[T; N]>().read()) }
89 }
90}
91
92#[derive(Proxy)]
93pub struct Buffer<const N: usize>(pub [u8; N]);
94
95impl<const N: usize> Marshal<()> for Buffer<N> {
96 fn write<W: BitWriter>(&self, writer: &mut W, _ctx: ()) -> Result<(), MarshalError> {
97 writer.align(1);
98 let (arr, _offset) = writer.reserve_and_advance::<N>(N, 0)?;
99 arr.copy_from_slice(&self.0[..]);
100 Ok(())
101 }
102}
103
104impl<'dm, const N: usize> Demarshal<'dm, ()> for Buffer<N> {
105 fn read(view: &mut BitView<'dm>, _ctx: ()) -> Result<Self, MarshalError> {
106 view.align(1);
107 view.take::<N>(N, 0).map(|x| Self(x.0.clone()))
108 }
109}
110
111impl Marshal<()> for String {
112 fn write<W: BitWriter>(&self, writer: &mut W, _ctx: ()) -> Result<(), MarshalError> {
113 writer.align(1);
114 let arr = writer.reserve_and_advance_aligned_slice(self.len() + 1)?;
115 let arr_str_bytes = &mut arr[0..self.len()];
116 arr_str_bytes.copy_from_slice(&self.as_bytes()[..]);
117 arr[arr.len() - 1] = 0;
118 Ok(())
119 }
120}
121
122impl<'de> Demarshal<'de, ()> for String {
123 fn read(view: &mut BitView<'de>, _ctx: ()) -> Result<Self, MarshalError> {
124 let buf = view.take_until(0u8)?;
125
126 unsafe {
127 Ok(String::from_utf8_unchecked(buf.to_vec()))
128 }
129 }
130}
131
132impl Marshal<()> for str {
133 fn write<W: BitWriter>(&self, writer: &mut W, _ctx: ()) -> Result<(), MarshalError> {
134 let arr = writer.reserve_and_advance_aligned_slice(self.len() + 1)?;
135 arr[0..self.len()].copy_from_slice(&self.as_bytes()[..]);
136 arr[arr.len() - 1] = 0;
137 Ok(())
138 }
139}
140
141impl<'dm> Demarshal<'dm, ()> for &'dm str {
142 fn read(view: &mut BitView<'dm>, _ctx: ()) -> Result<Self, MarshalError> {
143 let buf = view.take_until(0u8)?;
144 Ok(unsafe { core::str::from_utf8_unchecked(buf) })
145 }
146}
147
148impl<T: Marshal<()>, E: Marshal<()>> Marshal<()> for core::result::Result<T, E> {
149 fn write<W: BitWriter>(&self, writer: &mut W, _ctx: ()) -> Result<(), MarshalError> {
150 #[cfg(feature = "lasercan_nop_patch")]
152 unsafe { core::arch::asm!("nop") }
153
154 match self {
155 Ok(ok) => {
156 0u8.write(writer, ())?;
157 ok.write(writer, ())
158 },
159 Err(err) => {
160 1u8.write(writer, ())?;
161 err.write(writer, ())
162 },
163 }
164 }
165}
166
167impl<'dm, T: Demarshal<'dm, ()>, E: Demarshal<'dm, ()>> Demarshal<'dm, ()> for core::result::Result<T, E> {
168 fn read(view: &mut BitView<'dm>, _ctx: ()) -> Result<Self, MarshalError> {
169 let tag = u8::read(view, ())?;
170 match tag {
171 0 => {
172 T::read(view, ()).map(Ok)
173 },
174 _ => {
175 E::read(view, ()).map(Err)
176 },
177 }
178 }
179}
180
181impl<'a, C: Clone, T: Marshal<C>> Marshal<C> for [T] {
183 fn write<W: BitWriter>(&self, writer: &mut W, ctx: C) -> Result<(), MarshalError> {
184 for result in self.iter().map(|x| x.write(writer, ctx.clone())) {
188 result?;
189 }
190 Ok(())
191 }
192}
193
194impl<'a, C: Clone, T: Marshal<C>> Marshal<C> for Vec<T> {
195 fn write<W: BitWriter>(&self, writer: &mut W, ctx: C) -> Result<(), MarshalError> {
196 for result in self.iter().map(|x| x.write(writer, ctx.clone())) {
197 result?;
198 }
199 Ok(())
200 }
201}
202
203impl<'dm, C: Clone, T: Demarshal<'dm, C>> Demarshal<'dm, C> for Vec<T> {
204 fn read(view: &mut BitView<'dm>, ctx: C) -> Result<Self, MarshalError> {
205 let mut v = Vec::new();
206
207 loop {
208 match T::read(view, ctx.clone()) {
209 Ok(t) => v.push(t),
210 Err(MarshalError::BufferTooSmall) => break,
211 Err(e) => Err(e)?
212 }
213 }
214
215 Ok(v)
216 }
217}
218
219macro_rules! make_referent {
220 ($referent_name:ident, $owned_name:ident, $inner:ty, <$($generics:ident),*>) => {
221 #[repr(transparent)]
222 pub struct $referent_name <$($generics),*> {
223 #[allow(unused_parens)]
224 phantoms: PhantomData<($($generics),*)>,
225 inner: $inner
226 }
227
228 pub struct $owned_name <$($generics),*> where $inner: ToOwned {
229 #[allow(unused_parens)]
230 phantoms: PhantomData<($($generics),*)>,
231 inner: <$inner as ToOwned>::Owned
232 }
233
234 impl<$($generics),*> $owned_name<$($generics),*> where $inner: ToOwned {
235 pub fn new(inner: <$inner as ToOwned>::Owned) -> Self {
236 Self { phantoms: PhantomData, inner }
237 }
238 }
239
240 impl<'a, $($generics),*> From<&'a $inner> for &'a $referent_name <$($generics),*> {
241 fn from(r: &'a $inner) -> Self {
242 let ptr = r as *const $inner as *const $referent_name <$($generics),*>;
243 unsafe { &*ptr }
244 }
245 }
246
247 impl<'a, $($generics),*> AsRef<$inner> for &'a $referent_name <$($generics),*> {
248 fn as_ref(&self) -> &'a $inner {
249 &self.inner
250 }
251 }
252
253 impl<$($generics),*> Deref for $referent_name <$($generics),*> {
254 type Target = $inner;
255
256 fn deref(&self) -> &Self::Target {
257 &self.inner
258 }
259 }
260
261 impl<$($generics),*> Deref for $owned_name <$($generics),*> where $inner: ToOwned {
262 type Target = <$inner as ToOwned>::Owned;
263
264 fn deref(&self) -> &Self::Target {
265 &self.inner
266 }
267 }
268
269 impl<$($generics),*> DerefMut for $owned_name <$($generics),*> where $inner: ToOwned {
270 fn deref_mut(&mut self) -> &mut Self::Target {
271 &mut self.inner
272 }
273 }
274
275 impl<$($generics),*> Clone for $owned_name <$($generics),*> where $inner: ToOwned, <$inner as ToOwned>::Owned: Clone {
276 fn clone(&self) -> Self { Self { phantoms: PhantomData, inner: self.inner.clone() } }
277 }
278
279 impl<$($generics),*> core::fmt::Debug for $referent_name <$($generics),*> where $inner: core::fmt::Debug {
280 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.inner.fmt(f) }
281 }
282
283 impl<$($generics),*> core::fmt::Debug for $owned_name <$($generics),*> where $inner: ToOwned, <$inner as ToOwned>::Owned: core::fmt::Debug {
284 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.inner.fmt(f) }
285 }
286
287 impl<$($generics),*> PartialEq for $referent_name <$($generics),*> where $inner: PartialEq {
288 #[inline]
289 fn eq(&self, other: &Self) -> bool {
290 PartialEq::eq(&self.inner, &other.inner)
291 }
292 #[inline]
293 fn ne(&self, other: &Self) -> bool {
294 PartialEq::ne(&self.inner, &other.inner)
295 }
296 }
297
298 impl<$($generics),*> PartialEq for $owned_name <$($generics),*> where $inner: ToOwned, <$inner as ToOwned>::Owned: PartialEq {
299 #[inline]
300 fn eq(&self, other: &Self) -> bool {
301 PartialEq::eq(&self.inner, &other.inner)
302 }
303 #[inline]
304 fn ne(&self, other: &Self) -> bool {
305 PartialEq::ne(&self.inner, &other.inner)
306 }
307 }
308
309 impl<$($generics),*> Borrow<$referent_name <$($generics),*>> for $owned_name <$($generics),*> where $inner: ToOwned {
310 fn borrow<'a>(&'a self) -> &'a $referent_name<$($generics),*> {
311 let ptr = Borrow::borrow(&self.inner) as *const $inner as *const $referent_name <$($generics),*>;
312 unsafe { &*ptr }
313 }
314 }
315
316 impl<$($generics),*> ToOwned for $referent_name <$($generics),*> where $inner: ToOwned {
317 type Owned = $owned_name <$($generics),*>;
318
319 fn to_owned(&self) -> Self::Owned {
320 $owned_name { phantoms: PhantomData, inner: self.inner.to_owned() }
321 }
322 }
323
324 impl<CTX, $($generics),*> Marshal<CTX> for $owned_name <$($generics),*> where $inner: ToOwned, $referent_name<$($generics),*>: Marshal<CTX> {
325 fn write<W: BitWriter>(&self, writer: &mut W, ctx: CTX) -> Result<(), MarshalError> {
326 Marshal::<CTX>::write(Borrow::<$referent_name <$($generics),*>>::borrow(self), writer, ctx)
327 }
328 }
329
330 #[cfg(feature = "serde")]
331 impl<$($generics),*> serde::Serialize for $referent_name<$($generics),*> where $inner: serde::Serialize {
332 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
333 where
334 S: serde::Serializer
335 {
336 self.inner.serialize(serializer)
337 }
338 }
339
340 #[cfg(feature = "serde")]
341 impl<$($generics),*> serde::Serialize for $owned_name<$($generics),*> where $inner: ToOwned + serde::Serialize {
342 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
343 where
344 S: serde::Serializer
345 {
346 Borrow::<$referent_name <$($generics),*>>::borrow(self).serialize(serializer)
347 }
348 }
349
350 #[cfg(feature = "serde")]
351 impl<'de, $($generics),*> serde::de::Deserialize<'de> for $owned_name<$($generics),*> where $inner: ToOwned, <$inner as ToOwned>::Owned: serde::de::Deserialize<'de> {
352 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
353 where
354 D: serde::Deserializer<'de>
355 {
356 let t = <$inner as ToOwned>::Owned::deserialize(deserializer)?;
357 Ok(Self { phantoms: PhantomData, inner: t })
358 }
359 }
360
361 #[cfg(feature = "schema")]
362 impl<$($generics),*> schemars::JsonSchema for $referent_name<$($generics),*> where $inner: schemars::JsonSchema {
363 fn schema_name() -> String {
364 <$inner>::schema_name()
365 }
366
367 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
368 <$inner>::json_schema(gen)
369 }
370
371 fn is_referenceable() -> bool {
372 <$inner>::is_referenceable()
373 }
374
375 fn schema_id() -> Cow<'static, str> {
376 <$inner>::schema_id()
377 }
378 }
379
380 #[cfg(feature = "schema")]
381 impl<$($generics),*> schemars::JsonSchema for $owned_name<$($generics),*> where $inner: ToOwned, <$inner as ToOwned>::Owned: schemars::JsonSchema {
382 fn schema_name() -> String {
383 <$inner as ToOwned>::Owned::schema_name()
384 }
385
386 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
387 <$inner as ToOwned>::Owned::json_schema(gen)
388 }
389
390 fn is_referenceable() -> bool {
391 <$inner as ToOwned>::Owned::is_referenceable()
392 }
393
394 fn schema_id() -> Cow<'static, str> {
395 <$inner as ToOwned>::Owned::schema_id()
396 }
397 }
398 };
399}
400
401make_referent!(Payload, PayloadOwned, [u8], <>);
402make_referent!(LengthTaggedPayload, LengthTaggedPayloadOwned, [u8], <L>);
403make_referent!(LengthTaggedSlice, LengthTaggedVec, [T], <L, T>);
404
405impl Marshal<()> for Payload {
406 fn write<W: BitWriter>(&self, writer: &mut W, _: ()) -> Result<(), MarshalError> {
407 let arr = writer.reserve_and_advance_aligned_slice(self.inner.len())?;
408 arr.copy_from_slice(&self.inner);
409 Ok(())
410 }
411}
412
413impl<'dm> Demarshal<'dm, ()> for &'dm Payload {
414 fn read(view: &mut BitView<'dm>, _: ()) -> Result<Self, MarshalError> {
415 view.take_remaining().map(Into::into)
416 }
417}
418
419impl<'dm> Demarshal<'dm, ()> for PayloadOwned {
420 fn read(view: &mut BitView<'dm>, _: ()) -> Result<Self, MarshalError> {
421 let m = view.take_remaining()?;
422 Ok(PayloadOwned::new(m.to_vec()))
423 }
424}
425
426impl<L: TryFrom<usize> + Marshal<()>> Marshal<()> for LengthTaggedPayload<L> {
427 fn write<W: BitWriter>(&self, writer: &mut W, _: ()) -> Result<(), MarshalError> {
428 match L::try_from(self.inner.len()) {
429 Ok(v) => {
430 v.write(writer, ())?;
431 let arr = writer.reserve_and_advance_aligned_slice(self.inner.len())?;
432 arr.copy_from_slice(&self.inner);
433 Ok(())
434 },
435 Err(_) => Err(MarshalError::CoercionError),
436 }
437 }
438}
439
440impl<'dm, L: TryInto<usize> + DemarshalOwned> Demarshal<'dm, ()> for &'dm LengthTaggedPayload<L> {
441 fn read(view: &mut BitView<'dm>, _: ()) -> Result<Self, MarshalError> {
442 let l = L::read(view, ())?;
443 let as_usize = l.try_into().map_err(|_| MarshalError::CoercionError)?;
444 view.take_aligned_slice(as_usize).map(Into::into)
445 }
446}
447
448impl<'dm, L: TryInto<usize> + DemarshalOwned> Demarshal<'dm, ()> for LengthTaggedPayloadOwned<L> {
449 fn read(view: &mut BitView<'dm>, _: ()) -> Result<Self, MarshalError> {
450 let l = L::read(view, ())?;
451 let as_usize = l.try_into().map_err(|_| MarshalError::CoercionError)?;
452 Ok(LengthTaggedPayloadOwned::new(view.take_aligned_slice(as_usize)?.to_vec()))
453 }
454}
455
456impl<C: Clone, T: Marshal<C>, L: TryFrom<usize> + Marshal<()>> Marshal<C> for LengthTaggedSlice<L, T> {
457 fn write<W: BitWriter>(&self, writer: &mut W, ctx: C) -> Result<(), MarshalError> {
458 match L::try_from(self.inner.len()) {
459 Ok(v) => {
460 v.write(writer, ())?;
461 for result in self.inner.iter().map(|x| x.write(writer, ctx.clone())) {
462 result?;
463 }
464 Ok(())
465 },
466 Err(_) => Err(MarshalError::CoercionError),
467 }
468 }
469}
470
471impl<'dm, C: Clone, T: Demarshal<'dm, C>, L: TryInto<usize> + DemarshalOwned> Demarshal<'dm, C> for LengthTaggedVec<L, T>
472 where [T]: ToOwned<Owned = Vec<T>>
473{
474 fn read(view: &mut BitView<'dm>, ctx: C) -> Result<Self, MarshalError> {
475 let l = L::read(view, ())?;
476 let as_usize = l.try_into().map_err(|_| MarshalError::CoercionError)?;
477 let mut v = Vec::with_capacity(as_usize);
478 for _ in 0..as_usize {
479 v.push(T::read(view, ctx.clone())?);
480 }
481 Ok(LengthTaggedVec::new(v))
482 }
483}
484
485impl<'a, C, T> Marshal<C> for Cow<'a, T>
486where
487 T: ToOwned + ?Sized + Marshal<C>,
488{
489 fn write<'f, W: BitWriter>(&'f self, writer: &mut W, ctx: C) -> Result<(), MarshalError> {
490 let borrowed = self as &T;
491 borrowed.write(writer, ctx)
492 }
493}
494
495impl<'a, 'dm, C, T> Demarshal<'dm, C> for Cow<'a, T>
496where
497 T: ToOwned + ?Sized,
498 <T as ToOwned>::Owned: Demarshal<'dm, C>
499{
500 fn read(view: &mut BitView<'dm>, ctx: C) -> Result<Self, MarshalError> {
501 let t = <T as ToOwned>::Owned::read(view, ctx)?;
502 Ok(alloc::borrow::Cow::Owned(t))
503 }
504}
505
506#[derive(Proxy)]
507pub struct AsymmetricCow<'a, T: 'a + ToOwned + ?Sized>(pub Cow<'a, T>);
508
509impl<'a, T: 'a + ToOwned + ?Sized> AsymmetricCow<'a, T> {
510 pub fn into_owned(self) -> <T as ToOwned>::Owned {
511 self.0.into_owned()
512 }
513
514 pub fn to_mut(&mut self) -> &mut <T as ToOwned>::Owned {
515 self.0.to_mut()
516 }
517}
518
519impl<'a, C, T: ToOwned + ?Sized + Marshal<C>> Marshal<C> for AsymmetricCow<'a, T> {
520 fn write<W: BitWriter>(&self, writer: &mut W, ctx: C) -> Result<(), MarshalError> {
521 self.0.write(writer, ctx)
522 }
523}
524
525impl<'dm, C, T> Demarshal<'dm, C> for AsymmetricCow<'dm, T>
526where
527 T: ToOwned + ?Sized + 'dm,
528 &'dm T: Demarshal<'dm, C>
529{
530 fn read(view: &mut BitView<'dm>, ctx: C) -> Result<Self, MarshalError> {
531 let t = <&T>::read(view, ctx)?;
532 Ok(AsymmetricCow(alloc::borrow::Cow::Borrowed(t)))
533 }
534}
535
536impl<'a, T: 'static + ToOwned + ?Sized> IntoBoundedStatic for AsymmetricCow<'a, T> {
537 type Static = AsymmetricCow<'static, T>;
538
539 fn into_static(self) -> Self::Static {
540 AsymmetricCow::<'static, T>(self.0.into_static())
541 }
542}
543
544impl<'a, T: 'static + ToOwned + ?Sized> ToBoundedStatic for AsymmetricCow<'a, T> {
545 type Static = AsymmetricCow<'static, T>;
546
547 fn to_static(&self) -> Self::Static {
548 AsymmetricCow::<'static, T>(self.0.to_static())
549 }
550}
551
552#[cfg(test)]
553mod tests {
554 use crate::*;
555
556 #[test]
557 fn test_u8() {
558 let bytes = [0b1100_0101, 0b1010_0101];
559 let mut reader = BitView::new(&bytes[..]);
560 assert_eq!(u8::read(&mut reader, BitSpecification::<3>), Ok(0b110));
561 assert_eq!(u8::read(&mut reader, ()), Ok(0b0010_1101));
562 assert_eq!(u8::read(&mut reader, BitSpecification::<5>), Ok(0b00101));
563 assert_eq!(u8::read(&mut reader, BitSpecification::<1>), Err(MarshalError::BufferTooSmall));
564
565 let mut out = [0u8; 2];
566 let mut writer = BufferBitWriter::new(&mut out);
567 assert_eq!(0b11001u8.write(&mut writer, BitSpecification::<5>), Ok(()));
568 assert_eq!(0b1010_1101u8.write(&mut writer, BitSpecification::<8>), Ok(()));
569 assert_eq!(0b011u8.write(&mut writer, BitSpecification::<3>), Ok(()));
570 assert_eq!(out[0], 0b1100_1101);
571 assert_eq!(out[1], 0b0110_1011);
572 }
573
574 #[test]
575 fn test_u16() {
576 let bytes = [0b1100_0101, 0b1010_0101, 0b1011_1100];
577 let mut reader = BitView::new(&bytes[..]);
578 assert_eq!(u16::read(&mut reader, BitSpecification::<3>), Ok(0b110));
579 assert_eq!(u16::read(&mut reader, ()), Ok(0b0010_1101_0010_1101));
580 assert_eq!(u8::read(&mut reader, BitSpecification::<5>), Ok(0b11100));
581 assert_eq!(u8::read(&mut reader, BitSpecification::<1>), Err(MarshalError::BufferTooSmall));
582 }
583}