1use crate::{
2 buffer::Buffer,
3 deserialize::{Deserialize, DeserializeError, Deserializer},
4 formula::Formula,
5 serialize::{write_bytes, Serialize, Sizes},
6};
7
8pub struct Vlq;
58
59impl Formula for Vlq {
60 const MAX_STACK_SIZE: Option<usize> = None;
61 const EXACT_SIZE: bool = false;
62 const HEAPLESS: bool = true;
63}
64
65trait VlqType: Copy {
66 fn less_eq(&self, byte: u8) -> bool;
67
68 fn shr_byte_assign(&mut self) -> u8;
70
71 fn from_lsb(lsb: u8) -> Self;
73
74 fn shl_byte_set(&mut self, lsb: u8) -> bool;
77}
78
79impl VlqType for u8 {
80 #[inline(always)]
81 fn less_eq(&self, byte: u8) -> bool {
82 *self <= byte
83 }
84
85 #[inline(always)]
86 fn shr_byte_assign(&mut self) -> u8 {
87 core::mem::replace(self, 0)
88 }
89
90 #[inline(always)]
91 fn from_lsb(lsb: u8) -> Self {
92 lsb
93 }
94
95 #[inline(always)]
96 fn shl_byte_set(&mut self, lsb: u8) -> bool {
97 if *self > 0 {
98 return false;
99 }
100 *self = lsb;
101 true
102 }
103}
104
105macro_rules! impl_vlq_int {
106 ($($a:ident)*) => {
107 $(
108 impl VlqType for $a {
109 #[inline(always)]
110 fn less_eq(&self, byte: u8) -> bool {
111 *self <= $a::from(byte)
112 }
113
114 #[inline(always)]
115 fn shr_byte_assign(&mut self) -> u8 {
116 let lsb = *self as u8;
117 *self >>= 8;
118 lsb
119 }
120
121 #[inline(always)]
122 fn from_lsb(lsb: u8) -> Self {
123 $a::from(lsb)
124 }
125
126 #[inline(always)]
127 fn shl_byte_set(&mut self, lsb: u8) -> bool {
128 if self.leading_zeros() < 8 {
129 return false;
130 }
131 *self <<= 8;
132 *self |= $a::from(lsb);
133 true
134 }
135 }
136 )*
137 };
138}
139
140impl_vlq_int!(u16 u32 u64 u128 usize);
141
142impl<T> Serialize<Vlq> for T
143where
144 T: VlqType,
145{
146 #[inline(always)]
147 fn size_hint(&self) -> Option<Sizes> {
148 Some(size_hint(*self))
149 }
150
151 #[inline(always)]
152 fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
153 where
154 B: Buffer,
155 {
156 serialize(self, sizes, buffer)
157 }
158}
159
160impl<'de, T> Deserialize<'de, Vlq> for T
161where
162 T: VlqType,
163{
164 #[inline(always)]
165 fn deserialize(de: Deserializer<'de>) -> Result<Self, DeserializeError> {
166 deserialize(de)
167 }
168
169 #[inline(always)]
170 fn deserialize_in_place(
171 &mut self,
172 deserializer: Deserializer<'de>,
173 ) -> Result<(), DeserializeError> {
174 *self = deserialize(deserializer)?;
175 Ok(())
176 }
177}
178
179#[inline(always)]
180fn size_hint<T>(mut value: T) -> Sizes
181where
182 T: VlqType,
183{
184 let mut tail = 0;
185 loop {
186 if tail >= 8 {
187 if value.less_eq(0) {
188 break;
189 }
190 } else if value.less_eq(0xF) {
191 break;
192 }
193
194 if tail == 63 {
195 unimplemented!(
196 "Encoding for values that require more than 63 bytes is not implemented yet."
197 )
198 }
199 tail += 1;
200 value.shr_byte_assign();
201 }
202 Sizes::with_stack(tail + 1)
203}
204
205#[inline(always)]
206fn serialize<T, B>(mut value: T, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
207where
208 T: VlqType,
209 B: Buffer,
210{
211 let mut bytes = [0u8; 64];
212 let mut tail = 0;
213
214 loop {
215 if tail >= 8 {
216 if value.less_eq(0) {
217 bytes[usize::from(tail)] = 0x80 | tail;
218 return write_bytes(&bytes[..=usize::from(tail)], sizes, buffer);
219 }
220 } else if value.less_eq(0xF) {
221 let lsb = value.shr_byte_assign();
222 bytes[usize::from(tail)] = (tail << 4) | lsb;
223 return write_bytes(&bytes[..=usize::from(tail)], sizes, buffer);
224 }
225
226 if tail == 63 {
227 unimplemented!(
228 "Encoding for values that require more than 63 bytes is not implemented yet."
229 )
230 }
231
232 let lsb = value.shr_byte_assign();
233 bytes[usize::from(tail)] = lsb;
234 tail += 1;
235 }
236}
237
238#[inline(always)]
239fn deserialize<T>(mut de: Deserializer) -> Result<T, DeserializeError>
240where
241 T: VlqType,
242{
243 let header = de.read_bytes(1)?[0];
244
245 let (tail, msb) = match header {
246 0x00..=0x7F => (header >> 4, header & 0x0F),
247 0x80..=0xBF => (header & 0x3F, 0),
248 0xC0..=0xFF => {
249 unimplemented!(
250 "Decoding for values that require more than 63 bytes is not implemented yet."
251 )
252 }
253 };
254
255 let mut value = T::from_lsb(msb);
256
257 let tail = de.read_bytes(usize::from(tail))?;
258
259 for byte in tail.iter().rev() {
260 if !value.shl_byte_set(*byte) {
261 return Err(DeserializeError::IntegerOverflow);
262 }
263 }
264
265 Ok(value)
266}