compact_encoding/
fixedwidth.rs
1use crate::{
37 decode_u32, decode_u64, encode_u32, encode_u64, CompactEncoding, EncodingError, U32_SIZE,
38 U64_SIZE,
39};
40
41pub trait FixedWidthEncoding {
44 type Decode;
47 fn fw_encoded_size(&self) -> Result<usize, EncodingError>;
49
50 fn fw_encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError>;
52
53 fn fw_decode(buffer: &[u8]) -> Result<(Self::Decode, &[u8]), EncodingError>
56 where
57 Self: Sized;
58
59 fn as_fixed_width(&self) -> FixedWidthUint<Self> {
61 FixedWidthUint(self)
62 }
63}
64
65#[derive(Debug)]
67pub struct FixedWidthUint<'a, T: FixedWidthEncoding + ?Sized>(&'a T);
68
69impl<T: FixedWidthEncoding> CompactEncoding<T::Decode> for FixedWidthUint<'_, T> {
70 fn encoded_size(&self) -> Result<usize, EncodingError> {
71 self.0.fw_encoded_size()
72 }
73
74 fn encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
75 self.0.fw_encode(buffer)
76 }
77
78 fn decode(buffer: &[u8]) -> Result<(T::Decode, &[u8]), EncodingError>
79 where
80 Self: Sized,
81 {
82 <T as FixedWidthEncoding>::fw_decode(buffer)
83 }
84}
85
86impl FixedWidthEncoding for u32 {
87 type Decode = u32;
88
89 fn fw_encoded_size(&self) -> Result<usize, EncodingError> {
90 Ok(U32_SIZE)
91 }
92
93 fn fw_encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
94 encode_u32(*self, buffer)
95 }
96
97 fn fw_decode(buffer: &[u8]) -> Result<(Self::Decode, &[u8]), EncodingError>
98 where
99 Self: Sized,
100 {
101 decode_u32(buffer)
102 }
103}
104impl FixedWidthEncoding for u64 {
105 type Decode = u64;
106
107 fn fw_encoded_size(&self) -> Result<usize, EncodingError> {
108 Ok(U64_SIZE)
109 }
110
111 fn fw_encode<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a mut [u8], EncodingError> {
112 encode_u64(*self, buffer)
113 }
114
115 fn fw_decode(buffer: &[u8]) -> Result<(Self::Decode, &[u8]), EncodingError>
116 where
117 Self: Sized,
118 {
119 decode_u64(buffer)
120 }
121}
122
123pub type FixedWidthU32<'a> = FixedWidthUint<'a, u32>;
125pub type FixedWidthU64<'a> = FixedWidthUint<'a, u64>;
127#[cfg(test)]
128mod test {
129 use crate::{map_decode, to_encoded_bytes};
130
131 use super::*;
132
133 #[test]
134 fn fixed_width_u32() -> Result<(), EncodingError> {
135 let x = 42u32;
136 let fixed_buff = to_encoded_bytes!(x.as_fixed_width());
137 let var_buff = to_encoded_bytes!(x);
138 assert_eq!(fixed_buff, [42_u8, 0, 0, 0].into());
139 assert_eq!(var_buff, [42_u8].into());
140
141 let ((fixed_dec,), rest) = map_decode!(&fixed_buff, [FixedWidthU32]);
142 assert!(rest.is_empty());
143 assert_eq!(fixed_dec, x);
144
145 let ((var_dec,), rest) = map_decode!(&var_buff, [u32]);
146 assert!(rest.is_empty());
147 assert_eq!(var_dec, x);
148 Ok(())
149 }
150
151 #[test]
152 fn fixed_width_u64() -> Result<(), EncodingError> {
153 let x = 42u64;
154 let fixed_buff = to_encoded_bytes!(x.as_fixed_width());
155 let var_buff = to_encoded_bytes!(x);
156 assert_eq!(fixed_buff, [42, 0, 0, 0, 0, 0, 0, 0].into());
157 assert_eq!(var_buff, [42].into());
158
159 let ((fixed_dec,), rest) = map_decode!(&fixed_buff, [FixedWidthU64]);
160 assert!(rest.is_empty());
161 assert_eq!(fixed_dec, x);
162 Ok(())
163 }
164}