bin.rs (14409B)
1 extern crate alloc; 2 use alloc::borrow::Cow; 3 use core::str; 4 /// Unit error returned from [`Encode::encode_into_buffer`] and 5 /// [`Decode::decode_from_buffer`] to simply signal an error occurred. 6 pub(super) struct EncDecErr; 7 /// Encodes data as a binary format into a passed `Vec` buffer with the possibility 8 /// of erring. 9 pub(super) trait EncodeBufferFallible { 10 /// Error when [`Self::encode_into_buffer`] fails. 11 type Err; 12 /// Writes `self` into `buffer`. 13 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), Self::Err>; 14 } 15 /// Encodes data as a binary format into a passed `Vec` buffer. 16 pub(super) trait EncodeBuffer { 17 /// Writes `self` into `buffer`. 18 fn encode_into_buffer(&self, buffer: &mut Vec<u8>); 19 } 20 impl EncodeBuffer for u8 { 21 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 22 buffer.push(*self); 23 } 24 } 25 impl EncodeBuffer for u16 { 26 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 27 buffer.extend_from_slice(self.to_le_bytes().as_slice()); 28 } 29 } 30 impl EncodeBuffer for u32 { 31 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 32 buffer.extend_from_slice(self.to_le_bytes().as_slice()); 33 } 34 } 35 impl EncodeBuffer for u64 { 36 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 37 buffer.extend_from_slice(self.to_le_bytes().as_slice()); 38 } 39 } 40 impl EncodeBuffer for u128 { 41 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 42 buffer.extend_from_slice(self.to_le_bytes().as_slice()); 43 } 44 } 45 // `false as u8` is defined as 0. 46 /// `false` tag. 47 #[expect(clippy::as_conversions, reason = "this is safe, and we want a const")] 48 const FALSE: u8 = false as u8; 49 // `true as u8` is defined as 1. 50 /// `true` tag. 51 #[expect(clippy::as_conversions, reason = "this is safe, and we want a const")] 52 const TRUE: u8 = true as u8; 53 impl EncodeBuffer for bool { 54 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 55 buffer.push(if *self { TRUE } else { FALSE }); 56 } 57 } 58 // We don't implement `EncodeBuffer` for `[T]` since we only ever need `[u8]`; and one can specialize 59 // the implementation such that it's _a lot_ faster than a generic `T`. 60 impl EncodeBufferFallible for [u8] { 61 type Err = EncDecErr; 62 /// # Errors 63 /// 64 /// Errors iff `self.len() > usize::from(u16::MAX)`. 65 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), Self::Err> { 66 u16::try_from(self.len()) 67 .map_err(|_e| EncDecErr) 68 .map(|len| { 69 len.encode_into_buffer(buffer); 70 buffer.extend_from_slice(self); 71 }) 72 } 73 } 74 // We don't implement `EncodeBuffer` for `Vec<T>` since we only ever need `Vec<u8>`; and one can specialize 75 // the implementation such that it's _a lot_ faster than a generic `T`. 76 impl EncodeBufferFallible for Vec<u8> { 77 type Err = EncDecErr; 78 /// # Errors 79 /// 80 /// See [`[u8]::encode_into_buffer`]. 81 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), Self::Err> { 82 self.as_slice().encode_into_buffer(buffer) 83 } 84 } 85 // We don't implement `EncodeBuffer` for `[T; LEN]` since we only ever need `[u8; LEN]`; and one can specialize 86 // the implementation such that it's _a lot_ faster than a generic `T`. 87 impl<const LEN: usize> EncodeBuffer for [u8; LEN] 88 where 89 [u8; LEN]: Default, 90 { 91 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 92 buffer.extend_from_slice(self.as_slice()); 93 } 94 } 95 /// [`Option::None`] tag. 96 const NONE: u8 = 0; 97 /// [`Option::Some`] tag. 98 const SOME: u8 = 1; 99 impl<T: EncodeBuffer> EncodeBuffer for Option<T> { 100 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 101 match *self { 102 None => { 103 buffer.push(NONE); 104 } 105 Some(ref val) => { 106 buffer.push(SOME); 107 val.encode_into_buffer(buffer); 108 } 109 } 110 } 111 } 112 impl<T: EncodeBuffer, T2: EncodeBuffer> EncodeBuffer for (T, T2) { 113 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 114 self.0.encode_into_buffer(buffer); 115 self.1.encode_into_buffer(buffer); 116 } 117 } 118 impl EncodeBufferFallible for str { 119 type Err = EncDecErr; 120 /// # Errors 121 /// 122 /// See [`[u8]::encode_into_buffer`]. 123 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), Self::Err> { 124 self.as_bytes().encode_into_buffer(buffer) 125 } 126 } 127 impl EncodeBufferFallible for String { 128 type Err = EncDecErr; 129 /// # Errors 130 /// 131 /// See [`[u8]::encode_into_buffer`]. 132 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), Self::Err> { 133 self.as_str().encode_into_buffer(buffer) 134 } 135 } 136 impl EncodeBufferFallible for Cow<'_, str> { 137 type Err = EncDecErr; 138 /// # Errors 139 /// 140 /// See [`[u8]::encode_into_buffer`]. 141 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), Self::Err> { 142 self.as_ref().encode_into_buffer(buffer) 143 } 144 } 145 impl<T: EncodeBuffer + ?Sized> EncodeBuffer for &T { 146 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 147 (**self).encode_into_buffer(buffer); 148 } 149 } 150 impl<T: EncodeBuffer + ?Sized> EncodeBuffer for &mut T { 151 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 152 (**self).encode_into_buffer(buffer); 153 } 154 } 155 impl<T: EncodeBufferFallible + ?Sized> EncodeBufferFallible for &T { 156 type Err = T::Err; 157 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), Self::Err> { 158 (**self).encode_into_buffer(buffer) 159 } 160 } 161 impl<T: EncodeBufferFallible + ?Sized> EncodeBufferFallible for &mut T { 162 type Err = T::Err; 163 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), Self::Err> { 164 (**self).encode_into_buffer(buffer) 165 } 166 } 167 impl<T: EncodeBufferFallible> EncodeBufferFallible for Option<T> { 168 type Err = T::Err; 169 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), Self::Err> { 170 match *self { 171 None => { 172 buffer.push(NONE); 173 Ok(()) 174 } 175 Some(ref val) => { 176 buffer.push(SOME); 177 val.encode_into_buffer(buffer) 178 } 179 } 180 } 181 } 182 /// Decodes binary data generated by [`EncodeBuffer::encode_into_buffer`]. 183 pub(super) trait DecodeBuffer<'a>: Sized { 184 /// Error returned from [`Self::decode_from_buffer`]. 185 type Err; 186 /// Transforms a sub-`slice` of `data` into `Self`; and upon success, 187 /// mutates `data` to be the remaining portion. 188 /// 189 /// # Errors 190 /// 191 /// Errors iff `data` cannot be decoded into `Self`. 192 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err>; 193 } 194 impl<'a> DecodeBuffer<'a> for u8 { 195 type Err = EncDecErr; 196 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 197 data.split_first().ok_or(EncDecErr).map(|(&val, rem)| { 198 *data = rem; 199 val 200 }) 201 } 202 } 203 impl<'a> DecodeBuffer<'a> for u16 { 204 type Err = EncDecErr; 205 #[expect( 206 clippy::little_endian_bytes, 207 reason = "we must standardize the endianness to remove ambiguity" 208 )] 209 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 210 /// Number of bytes `u16` is made of. 211 const SIZE: usize = 2; 212 data.split_at_checked(SIZE) 213 .ok_or(EncDecErr) 214 .map(|(le_bytes, rem)| { 215 *data = rem; 216 let mut val = [0; SIZE]; 217 val.copy_from_slice(le_bytes); 218 Self::from_le_bytes(val) 219 }) 220 } 221 } 222 impl<'a> DecodeBuffer<'a> for u32 { 223 type Err = EncDecErr; 224 #[expect( 225 clippy::little_endian_bytes, 226 reason = "we must standardize the endianness to remove ambiguity" 227 )] 228 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 229 /// Number of bytes `u32` is made of. 230 const SIZE: usize = 4; 231 data.split_at_checked(SIZE) 232 .ok_or(EncDecErr) 233 .map(|(le_bytes, rem)| { 234 *data = rem; 235 let mut val = [0; SIZE]; 236 val.copy_from_slice(le_bytes); 237 Self::from_le_bytes(val) 238 }) 239 } 240 } 241 impl<'a> DecodeBuffer<'a> for u64 { 242 type Err = EncDecErr; 243 #[expect( 244 clippy::little_endian_bytes, 245 reason = "we must standardize the endianness to remove ambiguity" 246 )] 247 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 248 /// Number of bytes `u64` is made of. 249 const SIZE: usize = 8; 250 data.split_at_checked(SIZE) 251 .ok_or(EncDecErr) 252 .map(|(le_bytes, rem)| { 253 *data = rem; 254 let mut val = [0; SIZE]; 255 val.copy_from_slice(le_bytes); 256 Self::from_le_bytes(val) 257 }) 258 } 259 } 260 impl<'a> DecodeBuffer<'a> for u128 { 261 type Err = EncDecErr; 262 #[expect( 263 clippy::little_endian_bytes, 264 reason = "we must standardize the endianness to remove ambiguity" 265 )] 266 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 267 /// Number of bytes `u128` is made of. 268 const SIZE: usize = 16; 269 data.split_at_checked(SIZE) 270 .ok_or(EncDecErr) 271 .map(|(le_bytes, rem)| { 272 *data = rem; 273 let mut val = [0; SIZE]; 274 val.copy_from_slice(le_bytes); 275 Self::from_le_bytes(val) 276 }) 277 } 278 } 279 impl<'a> DecodeBuffer<'a> for bool { 280 type Err = EncDecErr; 281 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 282 u8::decode_from_buffer(data).and_then(|val| match val { 283 FALSE => Ok(false), 284 TRUE => Ok(true), 285 _ => Err(EncDecErr), 286 }) 287 } 288 } 289 // We don't implement `DecodeBuffer` for `&'a [T]` since we only ever need `&[u8]`; and one can specialize 290 // the implementation such that it's _a lot_ faster than a generic `T`. 291 impl<'a> DecodeBuffer<'a> for &'a [u8] { 292 type Err = EncDecErr; 293 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 294 u16::decode_from_buffer(data).and_then(|len| { 295 data.split_at_checked(usize::from(len)) 296 .ok_or(EncDecErr) 297 .map(|(val, rem)| { 298 *data = rem; 299 val 300 }) 301 }) 302 } 303 } 304 // We don't implement `DecodeBuffer` for `Vec<T>` since we only ever need `Vec<u8>`; and one can specialize 305 // the implementation such that it's _a lot_ faster than a generic `T`. 306 impl<'a> DecodeBuffer<'a> for Vec<u8> { 307 type Err = EncDecErr; 308 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 309 <&[u8]>::decode_from_buffer(data).map(ToOwned::to_owned) 310 } 311 } 312 // We don't implement `DecodeBuffer` for `[T; LEN]` since we only ever need `[u8; LEN]`; and one can specialize 313 // the implementation such that it's _a lot_ faster than a generic `T`. 314 impl<'a, const LEN: usize> DecodeBuffer<'a> for [u8; LEN] 315 where 316 [u8; LEN]: Default, 317 { 318 type Err = EncDecErr; 319 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 320 data.split_at_checked(LEN) 321 .ok_or(EncDecErr) 322 .map(|(val_slice, rem)| { 323 *data = rem; 324 let mut val = Self::default(); 325 val.copy_from_slice(val_slice); 326 val 327 }) 328 } 329 } 330 impl<'a, T> DecodeBuffer<'a> for Option<T> 331 where 332 T: DecodeBuffer<'a, Err = EncDecErr>, 333 { 334 type Err = EncDecErr; 335 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 336 u8::decode_from_buffer(data).and_then(|tag| match tag { 337 NONE => Ok(None), 338 SOME => T::decode_from_buffer(data).map(Some), 339 _ => Err(EncDecErr), 340 }) 341 } 342 } 343 impl<'a, T, T2> DecodeBuffer<'a> for (T, T2) 344 where 345 T: DecodeBuffer<'a, Err = EncDecErr>, 346 T2: DecodeBuffer<'a, Err = EncDecErr>, 347 { 348 type Err = EncDecErr; 349 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 350 T::decode_from_buffer(data) 351 .and_then(|val| T2::decode_from_buffer(data).map(|val2| (val, val2))) 352 } 353 } 354 impl<'a> DecodeBuffer<'a> for &'a str { 355 type Err = EncDecErr; 356 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 357 <&[u8]>::decode_from_buffer(data) 358 .and_then(|utf8| str::from_utf8(utf8).map_err(|_e| EncDecErr)) 359 } 360 } 361 impl<'a> DecodeBuffer<'a> for String { 362 type Err = EncDecErr; 363 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 364 <&str>::decode_from_buffer(data).map(ToOwned::to_owned) 365 } 366 } 367 /// Encodes `self` into a "primitive"-like type that can be saved to persistent storage 368 /// and later decoded via [`Decode::decode`]. 369 /// 370 /// The purpose of this trait is to transform `Self` into something "easily" consumable by persistent 371 /// storage which already has some form of inherent metadata (e.g., a column in a relational database (RDB)). 372 pub trait Encode { 373 /// "Primitive"-like type that `self` will be converted into. This should be one of the following: 374 /// * [`u8`] 375 /// * [`i8`] 376 /// * [`u16`] 377 /// * [`i16`] 378 /// * [`u32`] 379 /// * [`i32`] 380 /// * [`u64`] 381 /// * [`i64`] 382 /// * [`u128`] 383 /// * [`i128`] 384 /// * [`f32`] 385 /// * [`f64`] 386 /// * [`bool`] 387 /// * `&[u8]` 388 /// * [`&str`](prim@str) 389 /// * `[u8; N]` 390 /// * `Vec<u8>` 391 /// * [`String`] 392 type Output<'a> 393 where 394 Self: 'a; 395 /// Error returned when encoding fails. 396 type Err; 397 /// Transforms `self` into a "primitive"-like type. 398 /// 399 /// # Errors 400 /// 401 /// Errors iff `self` cannot be encoded into [`Self::Output`]. 402 fn encode(&self) -> Result<Self::Output<'_>, Self::Err>; 403 } 404 /// Decodes a "primitive"-like instance that was created via [`Encode::encode`] 405 /// into `Self`. 406 pub trait Decode: Sized { 407 /// "Primitive"-like input to be decoded. 408 /// 409 /// This should be the same as or the "owned" version of the corresponding [`Encode::Output`]. For example if 410 /// `Encode::Output` is `&[u8]`, then this should be `&[u8]` or `Vec<u8>`. 411 type Input<'a>; 412 /// Error returned when decoding fails. 413 type Err; 414 /// Decodes `input` into `Self`. Note `input` must not have any trailing data. 415 /// 416 /// # Errors 417 /// 418 /// Errors iff `input` cannot be decoded into `Self`. 419 fn decode(input: Self::Input<'_>) -> Result<Self, Self::Err>; 420 }