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
15pub 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 }
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}