1use crate::buf::{ReadBuf, WriteBuf};
33use crate::error::{Error, Result};
34use crate::varint;
35
36pub trait Encode {
65 #[must_use]
67 fn encoded_size(&self) -> usize;
68
69 fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()>;
76}
77
78pub trait Decode<'de>: Sized {
107 fn decode(buf: &mut ReadBuf<'de>) -> Result<Self>;
114}
115
116impl Encode for u8 {
117 #[inline]
118 fn encoded_size(&self) -> usize {
119 1
120 }
121 #[inline]
122 fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
123 buf.write_u8(*self)
124 }
125}
126
127impl<'de> Decode<'de> for u8 {
128 #[inline]
129 fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
130 buf.read_u8()
131 }
132}
133
134impl Encode for i8 {
135 #[inline]
136 fn encoded_size(&self) -> usize {
137 1
138 }
139 #[inline]
140 fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
141 buf.write_i8(*self)
142 }
143}
144
145impl<'de> Decode<'de> for i8 {
146 #[inline]
147 fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
148 buf.read_i8()
149 }
150}
151
152impl Encode for bool {
153 #[inline]
154 fn encoded_size(&self) -> usize {
155 1
156 }
157 #[inline]
158 fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
159 buf.write_u8(u8::from(*self))
160 }
161}
162
163impl<'de> Decode<'de> for bool {
165 #[inline]
166 fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
167 let value = match buf.peek_u8()? {
168 0 => false,
169 1 => true,
170 _ => return Err(Error::InvalidEncoding),
171 };
172 buf.consume(1);
173 Ok(value)
174 }
175}
176
177impl Encode for [u8] {
178 #[inline]
179 fn encoded_size(&self) -> usize {
180 self.len()
181 }
182 #[inline]
183 fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
184 buf.write_bytes(self)
185 }
186}
187
188impl<const N: usize> Encode for [u8; N] {
189 #[inline]
190 fn encoded_size(&self) -> usize {
191 N
192 }
193 #[inline]
194 fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
195 buf.write_bytes(self)
196 }
197}
198
199impl<'de, const N: usize> Decode<'de> for [u8; N] {
200 #[inline]
201 fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
202 buf.read_array()
203 }
204}
205
206impl<'de, const N: usize> Decode<'de> for &'de [u8; N] {
207 #[inline]
208 fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
209 buf.read_array_ref()
210 }
211}
212
213#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
231pub struct Be<T>(pub T);
232
233#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
248pub struct Le<T>(pub T);
249
250#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
274pub struct Varint<T>(pub T);
275
276macro_rules! fixed_width_impls {
277 ($($ty:ty: $read_be:ident, $write_be:ident, $read_le:ident, $write_le:ident;)*) => {$(
278 impl Encode for Be<$ty> {
279 #[inline]
280 fn encoded_size(&self) -> usize {
281 core::mem::size_of::<$ty>()
282 }
283 #[inline]
284 fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
285 buf.$write_be(self.0)
286 }
287 }
288
289 impl<'de> Decode<'de> for Be<$ty> {
290 #[inline]
291 fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
292 buf.$read_be().map(Be)
293 }
294 }
295
296 impl Encode for Le<$ty> {
297 #[inline]
298 fn encoded_size(&self) -> usize {
299 core::mem::size_of::<$ty>()
300 }
301 #[inline]
302 fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
303 buf.$write_le(self.0)
304 }
305 }
306
307 impl<'de> Decode<'de> for Le<$ty> {
308 #[inline]
309 fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
310 buf.$read_le().map(Le)
311 }
312 }
313 )*};
314}
315
316fixed_width_impls! {
317 u16: read_u16_be, write_u16_be, read_u16_le, write_u16_le;
318 u32: read_u32_be, write_u32_be, read_u32_le, write_u32_le;
319 u64: read_u64_be, write_u64_be, read_u64_le, write_u64_le;
320 u128: read_u128_be, write_u128_be, read_u128_le, write_u128_le;
321 i16: read_i16_be, write_i16_be, read_i16_le, write_i16_le;
322 i32: read_i32_be, write_i32_be, read_i32_le, write_i32_le;
323 i64: read_i64_be, write_i64_be, read_i64_le, write_i64_le;
324 i128: read_i128_be, write_i128_be, read_i128_le, write_i128_le;
325 f32: read_f32_be, write_f32_be, read_f32_le, write_f32_le;
326 f64: read_f64_be, write_f64_be, read_f64_le, write_f64_le;
327}
328
329macro_rules! varint_impls {
330 ($($ty:ty: $len:path, $encode:path, $decode:path;)*) => {$(
331 impl Encode for Varint<$ty> {
332 #[inline]
333 fn encoded_size(&self) -> usize {
334 $len(self.0)
335 }
336 #[inline]
337 fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
338 $encode(self.0, buf)
339 }
340 }
341
342 impl<'de> Decode<'de> for Varint<$ty> {
343 #[inline]
344 fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
345 $decode(buf).map(Varint)
346 }
347 }
348 )*};
349}
350
351varint_impls! {
352 u16: varint::encoded_len_u16, varint::encode_u16, varint::decode_u16;
353 u32: varint::encoded_len_u32, varint::encode_u32, varint::decode_u32;
354 u64: varint::encoded_len_u64, varint::encode_u64, varint::decode_u64;
355 usize: varint::encoded_len_usize, varint::encode_usize, varint::decode_usize;
356 i32: varint::encoded_len_i32, varint::encode_i32, varint::decode_i32;
357 i64: varint::encoded_len_i64, varint::encode_i64, varint::decode_i64;
358}
359
360macro_rules! tuple_impls {
361 ($(($($name:ident $idx:tt),+);)*) => {$(
362 impl<$($name: Encode),+> Encode for ($($name,)+) {
363 #[inline]
364 fn encoded_size(&self) -> usize {
365 0 $(+ self.$idx.encoded_size())+
366 }
367 #[inline]
368 fn encode(&self, buf: &mut WriteBuf<'_>) -> Result<()> {
369 if self.encoded_size() > buf.remaining() {
372 return Err(Error::BufferFull);
373 }
374 let start = buf.position();
375 let result = (|| {
376 $(self.$idx.encode(buf)?;)+
377 Ok(())
378 })();
379 if result.is_err() {
380 buf.rewind(start);
381 }
382 result
383 }
384 }
385
386 impl<'de, $($name: Decode<'de>),+> Decode<'de> for ($($name,)+) {
387 #[inline]
388 fn decode(buf: &mut ReadBuf<'de>) -> Result<Self> {
389 let mut scratch = buf.clone();
390 let value = ($($name::decode(&mut scratch)?,)+);
391 *buf = scratch;
392 Ok(value)
393 }
394 }
395 )*};
396}
397
398tuple_impls! {
399 (A 0, B 1);
400 (A 0, B 1, C 2);
401 (A 0, B 1, C 2, D 3);
402 (A 0, B 1, C 2, D 3, E 4);
403 (A 0, B 1, C 2, D 3, E 4, F 5);
404}
405
406#[cfg(test)]
407mod tests {
408 use super::*;
409
410 struct Rejects;
412
413 impl Encode for Rejects {
414 fn encoded_size(&self) -> usize {
415 1
416 }
417 fn encode(&self, _buf: &mut WriteBuf<'_>) -> Result<()> {
418 Err(Error::InvalidEncoding)
419 }
420 }
421
422 fn round_trip<T>(value: T) -> T
423 where
424 T: Encode + for<'de> Decode<'de> + PartialEq + core::fmt::Debug,
425 {
426 let mut out = [0u8; 64];
427 let mut buf = WriteBuf::new(&mut out);
428 value.encode(&mut buf).unwrap();
429 let n = buf.position();
430 assert_eq!(n, value.encoded_size(), "encoded_size must be exact");
431 let mut r = ReadBuf::new(&out[..n]);
432 let decoded = T::decode(&mut r).unwrap();
433 assert!(r.is_empty());
434 decoded
435 }
436
437 #[test]
438 fn primitive_round_trips() {
439 assert_eq!(round_trip(0xABu8), 0xAB);
440 assert_eq!(round_trip(-5i8), -5);
441 assert!(round_trip(true));
442 assert!(!round_trip(false));
443 assert_eq!(round_trip([1u8, 2, 3]), [1, 2, 3]);
444 }
445
446 #[test]
447 fn wrapper_round_trips() {
448 assert_eq!(round_trip(Be(u16::MAX)), Be(u16::MAX));
449 assert_eq!(round_trip(Le(0x0102_0304_u32)), Le(0x0102_0304));
450 assert_eq!(round_trip(Be(u64::MAX - 1)), Be(u64::MAX - 1));
451 assert_eq!(round_trip(Le(u128::MAX / 3)), Le(u128::MAX / 3));
452 assert_eq!(round_trip(Be(i32::MIN)), Be(i32::MIN));
453 assert_eq!(round_trip(Le(i64::MIN)), Le(i64::MIN));
454 assert_eq!(round_trip(Be(i128::MIN)), Be(i128::MIN));
455 assert_eq!(round_trip(Le(-3i16)), Le(-3));
456 assert_eq!(round_trip(Be(2.5f64)), Be(2.5));
457 assert_eq!(round_trip(Le(-0.5f64)), Le(-0.5));
458 assert_eq!(round_trip(Be(9.0f32)), Be(9.0));
459 for v in [0u16, 300, u16::MAX] {
460 assert_eq!(round_trip(Varint(v)), Varint(v));
461 }
462 for v in [0usize, 1 << 20, usize::MAX] {
463 assert_eq!(round_trip(Varint(v)), Varint(v));
464 }
465 assert_eq!(round_trip(Varint(u32::MAX)), Varint(u32::MAX));
466 assert_eq!(round_trip(Varint(u64::MAX)), Varint(u64::MAX));
467 assert_eq!(round_trip(Varint(i32::MIN)), Varint(i32::MIN));
468 assert_eq!(round_trip(Varint(i64::MAX)), Varint(i64::MAX));
469 }
470
471 #[test]
472 fn byte_order_is_explicit() {
473 let mut out = [0u8; 4];
474 let mut buf = WriteBuf::new(&mut out);
475 Be(0x0102u16).encode(&mut buf).unwrap();
476 Le(0x0102u16).encode(&mut buf).unwrap();
477 assert_eq!(out, [0x01, 0x02, 0x02, 0x01]);
478 }
479
480 #[test]
481 fn tuples_encode_in_order() {
482 let value = (1u8, Be(0x0203u16), Varint(300u32), true);
483 let mut out = [0u8; 16];
484 let mut buf = WriteBuf::new(&mut out);
485 value.encode(&mut buf).unwrap();
486 assert_eq!(buf.written(), &[1, 2, 3, 0xAC, 0x02, 1]);
487 assert_eq!(round_trip(value), value);
488 assert_eq!(round_trip((1u8, 2u8)), (1, 2));
489 assert_eq!(round_trip((1u8, 2u8, 3u8)), (1, 2, 3));
490 assert_eq!(round_trip((1u8, 2u8, 3u8, 4u8, 5u8)), (1, 2, 3, 4, 5));
491 assert_eq!(
492 round_trip((1u8, 2u8, 3u8, 4u8, 5u8, 6u8)),
493 (1, 2, 3, 4, 5, 6)
494 );
495 }
496
497 #[test]
498 fn tuple_decode_and_encode_are_atomic() {
499 let mut r = ReadBuf::new(&[7, 0x01]);
501 assert_eq!(<(u8, Be<u16>)>::decode(&mut r), Err(Error::UnexpectedEof));
502 assert_eq!(r.position(), 0);
503
504 let mut out = [0xEEu8; 2];
505 let mut buf = WriteBuf::new(&mut out);
506 assert_eq!((1u8, Be(2u16)).encode(&mut buf), Err(Error::BufferFull));
507 assert_eq!(buf.position(), 0);
508 assert_eq!(out, [0xEE, 0xEE], "a short buffer writes nothing");
509
510 let mut out = [0u8; 4];
512 let mut buf = WriteBuf::new(&mut out);
513 assert_eq!((1u8, Rejects).encode(&mut buf), Err(Error::InvalidEncoding));
514 assert_eq!(buf.position(), 0);
515 }
516
517 #[test]
518 fn bool_is_strict() {
519 let mut r = ReadBuf::new(&[2]);
520 assert_eq!(bool::decode(&mut r), Err(Error::InvalidEncoding));
521 assert_eq!(r.position(), 0);
522 assert_eq!(
523 bool::decode(&mut ReadBuf::new(&[])),
524 Err(Error::UnexpectedEof)
525 );
526 }
527
528 #[test]
529 fn byte_slices_and_array_refs() {
530 let mut out = [0u8; 8];
531 let mut buf = WriteBuf::new(&mut out);
532 let raw: &[u8] = b"wire";
533 assert_eq!(raw.encoded_size(), 4);
534 raw.encode(&mut buf).unwrap();
535 assert_eq!(buf.written(), b"wire");
536
537 let data = *b"abcdef";
538 let mut r = ReadBuf::new(&data);
539 let head = <&[u8; 4]>::decode(&mut r).unwrap();
540 assert_eq!(head, b"abcd");
541 assert_eq!(<[u8; 4]>::decode(&mut r), Err(Error::UnexpectedEof));
542 }
543
544 #[test]
545 fn encode_errors_propagate() {
546 let mut out = [0u8; 1];
547 let mut buf = WriteBuf::new(&mut out);
548 assert_eq!(Be(1u32).encode(&mut buf), Err(Error::BufferFull));
549 assert_eq!(Le(1u32).encode(&mut buf), Err(Error::BufferFull));
550 assert_eq!(Varint(300u32).encode(&mut buf), Err(Error::BufferFull));
551 assert_eq!(buf.position(), 0);
552 let mut r = ReadBuf::new(&[0x80]);
553 assert_eq!(Varint::<u64>::decode(&mut r), Err(Error::UnexpectedEof));
554 assert_eq!(Le::<u16>::decode(&mut r), Err(Error::UnexpectedEof));
555 assert_eq!(Be::<u16>::decode(&mut r), Err(Error::UnexpectedEof));
556 }
557}