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}