binbuf/
impls.rs

1use std::{array, marker::PhantomData};
2use crate::{bytes_ptr, fixed::{self}, BytesPtr, Entry, Fixed};
3pub use arb_num::Value as ArbNum;
4
5pub mod primitive;
6pub mod dynamic;
7pub mod arb_num;
8
9fixed! {
10    buf! { pub struct UnitBuf<P>((), P); }
11    impl I for () {
12        type Buf<P> = UnitBuf<P>;
13    }
14}
15
16impl Fixed for () {
17    const LEN: usize = 0;
18    fn encode(&self, _buf: fixed::BufMut<Self>) {}
19}
20impl fixed::Decode for () {
21    fn decode(_buf: fixed::BufConst<Self>) -> Self {}
22}
23
24pub struct OptionBuf<P: BytesPtr, T>(P, PhantomData<T>);
25
26impl<P: BytesPtr, T> Clone for OptionBuf<P, T> {
27    fn clone(&self) -> Self {
28        Self(self.0, PhantomData)
29    }
30}
31
32impl<P: BytesPtr, T> Copy for OptionBuf<P, T> {}
33
34impl<T> crate::Entry for Option<T> {
35    type Buf<P: fixed::Ptr> = OptionBuf<P, T>;
36    unsafe fn buf<P: fixed::Ptr>(ptr: P) -> Self::Buf<P> {
37        OptionBuf(ptr, PhantomData)
38    }
39    fn buf_ptr<P: fixed::Ptr>(buf: Self::Buf<P>) -> P {
40        buf.0
41    }
42}
43
44impl<P: BytesPtr, T: Fixed> fixed::Readable<Option<T>> for OptionBuf<P, T> {
45    fn write_to(self, buf: fixed::BufMut<Option<T>>) {
46        fixed::buf_copy_to::<Option<T>>(unsafe { Option::<T>::buf(buf.0.to_const()) }, buf);
47    }
48}
49
50impl<T: Fixed> Fixed for Option<T> {
51    const LEN: usize = T::LEN + 1;
52    fn encode(&self, buf: fixed::BufMut<Self>) {
53        match self {
54            Some(data) => {
55                buf.0.slice()[0] = 1;
56                unsafe { fixed::encode_ptr::<T>(buf.0.range_from(1), data) };
57            },
58            None => {
59                buf.0.slice()[0] = 0;
60            }
61        }
62    }
63}
64
65impl<T: fixed::Decode> fixed::Decode for Option<T> {
66    fn decode(buf: fixed::BufConst<Self>) -> Self {
67        match buf.0.slice()[0] {
68            1 => {
69                Some(unsafe { fixed::decode_ptr::<T>(buf.0.range_from(1)) })
70            },
71            _ => None,
72        }
73    }
74}
75
76fixed! {
77    buf! { pub struct PhantomDataBuf<P, T>(PhantomData<T>, P); }
78    impl<T> I for PhantomData<T> {
79        type Buf<P> = PhantomDataBuf<P, T>;
80    }
81}
82
83impl<T> Fixed for PhantomData<T> {
84    const LEN: usize = 0;
85    fn encode(&self, _buf: fixed::BufMut<Self>) { }
86}
87impl<T> fixed::Decode for PhantomData<T> {
88    fn decode(_buf: fixed::BufConst<Self>) -> Self {
89        PhantomData
90    }
91}
92
93fixed! {
94    buf! { pub struct ArrayBuf<P, T: Fixed, const N: usize>([T; N], P); }
95    impl<T: Fixed, const N: usize> I for [T; N] {
96        type Buf<P> = ArrayBuf<P, T, N>;
97    }
98}
99
100impl<T: Fixed, const N: usize> Fixed for [T; N] {
101    const LEN: usize = N * T::LEN;
102    default fn encode(&self, buf: fixed::BufMut<Self>) {
103        for idx in 0 .. N {
104            unsafe { fixed::encode_ptr(buf.0.range_at(idx * T::LEN, T::LEN), self.get_unchecked(idx)); }
105        }
106    }
107}
108impl<T: fixed::Decode, const N: usize> fixed::Decode for [T; N] {
109    default fn decode(buf: fixed::BufConst<Self>) -> Self {
110        array::from_fn(|idx| {
111            unsafe { fixed::decode_ptr(buf.0.range_at(idx * T::LEN, T::LEN)) }
112        })
113    }
114}
115
116impl<const N: usize> Fixed for [u8; N] {
117    fn encode(&self, buf: fixed::BufMut<Self>) {
118        buf.0.copy_from_slice(self);
119    }
120}
121impl<const N: usize> fixed::Decode for [u8; N] {
122    fn decode(buf: fixed::BufConst<Self>) -> Self {
123        unsafe { *buf.0.array() }
124    }
125}