bin.rs (14076B)
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 data.split_at_checked(2) 211 .ok_or(EncDecErr) 212 .map(|(le_bytes, rem)| { 213 *data = rem; 214 let mut val = [0; 2]; 215 val.copy_from_slice(le_bytes); 216 Self::from_le_bytes(val) 217 }) 218 } 219 } 220 impl<'a> DecodeBuffer<'a> for u32 { 221 type Err = EncDecErr; 222 #[expect( 223 clippy::little_endian_bytes, 224 reason = "we must standardize the endianness to remove ambiguity" 225 )] 226 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 227 data.split_at_checked(4) 228 .ok_or(EncDecErr) 229 .map(|(le_bytes, rem)| { 230 *data = rem; 231 let mut val = [0; 4]; 232 val.copy_from_slice(le_bytes); 233 Self::from_le_bytes(val) 234 }) 235 } 236 } 237 impl<'a> DecodeBuffer<'a> for u64 { 238 type Err = EncDecErr; 239 #[expect( 240 clippy::little_endian_bytes, 241 reason = "we must standardize the endianness to remove ambiguity" 242 )] 243 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 244 data.split_at_checked(8) 245 .ok_or(EncDecErr) 246 .map(|(le_bytes, rem)| { 247 *data = rem; 248 let mut val = [0; 8]; 249 val.copy_from_slice(le_bytes); 250 Self::from_le_bytes(val) 251 }) 252 } 253 } 254 impl<'a> DecodeBuffer<'a> for u128 { 255 type Err = EncDecErr; 256 #[expect( 257 clippy::little_endian_bytes, 258 reason = "we must standardize the endianness to remove ambiguity" 259 )] 260 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 261 data.split_at_checked(8) 262 .ok_or(EncDecErr) 263 .map(|(le_bytes, rem)| { 264 *data = rem; 265 let mut val = [0; 16]; 266 val.copy_from_slice(le_bytes); 267 Self::from_le_bytes(val) 268 }) 269 } 270 } 271 impl<'a> DecodeBuffer<'a> for bool { 272 type Err = EncDecErr; 273 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 274 u8::decode_from_buffer(data).and_then(|val| match val { 275 FALSE => Ok(false), 276 TRUE => Ok(true), 277 _ => Err(EncDecErr), 278 }) 279 } 280 } 281 // We don't implement `DecodeBuffer` for `&'a [T]` since we only ever need `&[u8]`; and one can specialize 282 // the implementation such that it's _a lot_ faster than a generic `T`. 283 impl<'a> DecodeBuffer<'a> for &'a [u8] { 284 type Err = EncDecErr; 285 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 286 u16::decode_from_buffer(data).and_then(|len| { 287 data.split_at_checked(usize::from(len)) 288 .ok_or(EncDecErr) 289 .map(|(val, rem)| { 290 *data = rem; 291 val 292 }) 293 }) 294 } 295 } 296 // We don't implement `DecodeBuffer` for `Vec<T>` since we only ever need `Vec<u8>`; and one can specialize 297 // the implementation such that it's _a lot_ faster than a generic `T`. 298 impl<'a> DecodeBuffer<'a> for Vec<u8> { 299 type Err = EncDecErr; 300 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 301 <&[u8]>::decode_from_buffer(data).map(ToOwned::to_owned) 302 } 303 } 304 // We don't implement `DecodeBuffer` for `[T; LEN]` since we only ever need `[u8; LEN]`; and one can specialize 305 // the implementation such that it's _a lot_ faster than a generic `T`. 306 impl<'a, const LEN: usize> DecodeBuffer<'a> for [u8; LEN] 307 where 308 [u8; LEN]: Default, 309 { 310 type Err = EncDecErr; 311 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 312 data.split_at_checked(LEN) 313 .ok_or(EncDecErr) 314 .map(|(val_slice, rem)| { 315 *data = rem; 316 let mut val = Self::default(); 317 val.copy_from_slice(val_slice); 318 val 319 }) 320 } 321 } 322 impl<'a, T> DecodeBuffer<'a> for Option<T> 323 where 324 T: DecodeBuffer<'a, Err = EncDecErr>, 325 { 326 type Err = EncDecErr; 327 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 328 u8::decode_from_buffer(data).and_then(|tag| match tag { 329 NONE => Ok(None), 330 SOME => T::decode_from_buffer(data).map(Some), 331 _ => Err(EncDecErr), 332 }) 333 } 334 } 335 impl<'a, T, T2> DecodeBuffer<'a> for (T, T2) 336 where 337 T: DecodeBuffer<'a, Err = EncDecErr>, 338 T2: DecodeBuffer<'a, Err = EncDecErr>, 339 { 340 type Err = EncDecErr; 341 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 342 T::decode_from_buffer(data) 343 .and_then(|val| T2::decode_from_buffer(data).map(|val2| (val, val2))) 344 } 345 } 346 impl<'a> DecodeBuffer<'a> for &'a str { 347 type Err = EncDecErr; 348 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 349 <&[u8]>::decode_from_buffer(data) 350 .and_then(|utf8| str::from_utf8(utf8).map_err(|_e| EncDecErr)) 351 } 352 } 353 impl<'a> DecodeBuffer<'a> for String { 354 type Err = EncDecErr; 355 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 356 <&str>::decode_from_buffer(data).map(ToOwned::to_owned) 357 } 358 } 359 /// Encodes `self` into a "primitive"-like type that can be saved to persistent storage 360 /// and later decoded via [`Decode::decode`]. 361 /// 362 /// The purpose of this trait is to transform `Self` into something "easily" consumable by persistent 363 /// storage which already has some form of inherent metadata (e.g., a column in a relational database (RDB)). 364 pub trait Encode { 365 /// "Primitive"-like type that `self` will be converted into. This should be one of the following: 366 /// * [`u8`] 367 /// * [`i8`] 368 /// * [`u16`] 369 /// * [`i16`] 370 /// * [`u32`] 371 /// * [`i32`] 372 /// * [`u64`] 373 /// * [`i64`] 374 /// * [`u128`] 375 /// * [`i128`] 376 /// * [`f32`] 377 /// * [`f64`] 378 /// * [`bool`] 379 /// * `&[u8]` 380 /// * [`&str`](prim@str) 381 /// * `[u8; N]` 382 /// * `Vec<u8>` 383 /// * [`String`] 384 type Output<'a> 385 where 386 Self: 'a; 387 /// Error returned when encoding fails. 388 type Err; 389 /// Transforms `self` into a "primitive"-like type. 390 /// 391 /// # Errors 392 /// 393 /// Errors iff `self` cannot be encoded into [`Self::Output`]. 394 fn encode(&self) -> Result<Self::Output<'_>, Self::Err>; 395 } 396 /// Decodes a "primitive"-like instance that was created via [`Encode::encode`] 397 /// into `Self`. 398 pub trait Decode: Sized { 399 /// "Primitive"-like input to be decoded. 400 /// 401 /// This should be the same as or the "owned" version of the corresponding [`Encode::Output`]. For example if 402 /// `Encode::Output` is `&[u8]`, then this should be `&[u8]` or `Vec<u8>`. 403 type Input<'a>; 404 /// Error returned when decoding fails. 405 type Err; 406 /// Decodes `input` into `Self`. Note `input` must not have any trailing data. 407 /// 408 /// # Errors 409 /// 410 /// Errors iff `input` cannot be decoded into `Self`. 411 fn decode(input: Self::Input<'_>) -> Result<Self, Self::Err>; 412 }