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