binbuf/
fixed.rs

1#![allow(type_alias_bounds)]
2
3use std::cmp::Ordering;
4
5pub use lens::Instance as Lens;
6pub use crate::{Entry, bytes_ptr as ptr, entry::buf_to_const};
7pub use ptr::Instance as Ptr;
8
9pub mod lens;
10
11pub type Buf<T: Instance, P> = T::Buf<P>;
12pub type BufConst<T: Instance> = T::Buf<ptr::Const>;
13pub type BufMut<T: Instance> = T::Buf<ptr::Mut>;
14
15// fn encode_to_owned<T: Codable>(value: &T) -> BufOwned<T> {
16//     let mut buf = T::buf(unsafe { bytes::Owned::new(vec![0; T::len()].into_boxed_slice()) });
17//     value.encode(T::buf_owned_as_mut(&mut buf));
18//     buf
19// }
20
21pub fn encode_to_array<T: Instance>(value: &T) -> [u8; T::LEN] {
22    let mut array = [0; T::LEN];
23    value.encode(unsafe { T::buf(ptr::Mut::from_slice(&mut array)) });
24    array
25}
26
27pub fn buf_swap<T: Instance>(a: BufMut<T>, b: BufMut<T>) {
28    T::buf_ptr(a).swap(T::buf_ptr(b))
29}
30
31pub fn buf_copy_to<T: Instance>(src: BufConst<T>, dst: BufMut<T>) {
32    T::buf_ptr(src).copy_to(T::buf_ptr(dst))
33}
34
35pub fn decode<T: Decode, P: Ptr>(buf: T::Buf<P>) -> T {
36    T::decode(buf_to_const::<T, P>(buf))
37}
38
39pub unsafe fn decode_ptr<T: Decode>(ptr: ptr::Const) -> T {
40    T::decode(T::buf(ptr))
41}
42
43pub unsafe fn decode_slice<T: Decode>(slice: &[u8]) -> T {
44    decode_ptr::<T>(ptr::Const::from_slice(slice))
45}
46
47pub unsafe fn encode_ptr<T: Instance>(ptr: ptr::Mut, value: &T) {
48    T::encode(value, T::buf(ptr))
49}
50
51pub unsafe fn encode_slice<T: Instance>(slice: &mut [u8], value: impl Readable<T>) {
52    value.write_to(T::buf(ptr::Mut::from_slice(slice)))
53}
54
55pub trait Instance: Entry {
56    const LEN: usize;
57    fn encode(&self, buf: BufMut<Self>);
58    
59    // Future plans.
60    // fn is_valid(buf: BufConst<Self>) -> bool {
61    //     unimplemented!()
62    // }
63    // fn decode_checked(buf: BufConst<Self>) -> Option<Self> {
64    //     if Self::is_valid(buf) {
65    //         Some(Self::decode(buf))
66    //     } else {
67    //         None
68    //     }
69    // }
70
71    // fn encode_to_owned(&self) -> BufOwned<Self> where Self: Sized {
72    //     encode_to_owned(self)
73    // }
74}
75
76pub trait Decode: Instance {
77    fn decode(buf: BufConst<Self>) -> Self;
78}
79
80pub trait Readable<T: Instance> {
81    fn write_to(self, buf: BufMut<T>);
82}
83
84impl<T: Instance> Readable<T> for &T {
85    fn write_to(self, buf: BufMut<T>) {
86        self.encode(buf);
87    }
88}
89
90pub trait BufPartialEq<T: Instance>: Readable<T> + Sized {
91    fn buf_eq(self, rhs: BufConst<T>) -> bool;
92}
93
94pub trait BufEq<T: Instance>: BufPartialEq<T> {}
95
96impl<T: Decode + PartialEq> BufPartialEq<T> for &T {
97    default fn buf_eq(self, rhs: BufConst<T>) -> bool {
98        self == &T::decode(rhs)
99    }
100}
101
102impl<T: Decode + Eq> BufEq<T> for &T {}
103
104pub trait BufPartialOrd<T: Instance>: BufPartialEq<T> {
105    fn buf_partial_cmp(self, rhs: BufConst<T>) -> Option<Ordering>;
106    fn buf_lt(self, rhs: BufConst<T>) -> bool {
107        matches!(self.buf_partial_cmp(rhs), Some(Ordering::Less))
108    }
109    fn buf_gt(self, rhs: BufConst<T>) -> bool {
110        matches!(self.buf_partial_cmp(rhs), Some(Ordering::Greater))
111    }
112}
113
114pub trait BufOrd<T: Instance>: BufPartialOrd<T> {
115    fn buf_cmp(self, rhs: BufConst<T>) -> Ordering;
116}
117
118impl<T: Decode + PartialOrd> BufPartialOrd<T> for &T {
119    default fn buf_partial_cmp(self, rhs: BufConst<T>) -> Option<Ordering> {
120        self.partial_cmp(&T::decode(rhs))
121    }
122}
123
124impl<T: Decode + Ord> BufOrd<T> for &T {
125    fn buf_cmp(self, rhs: BufConst<T>) -> Ordering {
126        self.cmp(&T::decode(rhs))
127    }
128}