|
1 | 1 | #![forbid(unsafe_code, missing_docs)] |
2 | 2 | #![cfg_attr(test, deny(warnings))] |
3 | | - |
| 3 | +// TODO compact encoding currently has no way to encode/decode`std::net::SocketAddr` because it |
| 4 | +// could contain a ipv4 OR an ipv6 address and the current ipv4 encoding has no way for it to |
| 5 | +// distinguish itself. |
| 6 | +// So should this be a panic? |
4 | 7 | //! # Series of compact encoding schemes for building small and fast parsers and serializers |
5 | 8 | //! |
6 | 9 | //! Binary compatible with the |
@@ -444,8 +447,20 @@ macro_rules! map_decode { |
444 | 447 | }}; |
445 | 448 | } |
446 | 449 |
|
447 | | -/// helper for mapping the first element of a two eleent tuple |
| 450 | +#[macro_export] |
| 451 | +/// Helper for mapping the first element of a two eleent tuple. |
| 452 | +/// This is useful for cleanly handling the result of CompactEncoding::decode. |
448 | 453 | macro_rules! map_first { |
| 454 | + ($res:expr, $f:expr) => {{ |
| 455 | + let (one, two) = $res; |
| 456 | + let mapped = $f(one); |
| 457 | + (mapped, two) |
| 458 | + }}; |
| 459 | +} |
| 460 | + |
| 461 | +#[macro_export] |
| 462 | +/// like [`map_first`] but the mapping should return a result. |
| 463 | +macro_rules! map_first_result { |
449 | 464 | ($res:expr, $f:expr) => {{ |
450 | 465 | let (one, two) = $res; |
451 | 466 | let mapped = $f(one)?; |
@@ -618,16 +633,14 @@ pub fn decode_usize(buffer: &[u8]) -> Result<(usize, &[u8]), EncodingError> { |
618 | 633 | let ([first], rest) = take_array::<1>(buffer)?; |
619 | 634 | Ok(match first { |
620 | 635 | x if x < U16_SIGNIFIER => (x.into(), rest), |
621 | | - U16_SIGNIFIER => map_first!(decode_u16(rest)?, |x: u16| Ok(x.into())), |
| 636 | + U16_SIGNIFIER => map_first!(decode_u16(rest)?, |x: u16| x.into()), |
622 | 637 | U32_SIGNIFIER => { |
623 | | - map_first!(decode_u32(rest)?, |val| usize::try_from(val).map_err( |
624 | | - |_| EncodingError::overflow("Could not convert u32 to usize") |
625 | | - )) |
| 638 | + map_first_result!(decode_u32(rest)?, |val| usize::try_from(val) |
| 639 | + .map_err(|_| EncodingError::overflow("Could not convert u32 to usize"))) |
626 | 640 | } |
627 | 641 | _ => { |
628 | | - map_first!(decode_u64(rest)?, |val| usize::try_from(val).map_err( |
629 | | - |_| EncodingError::overflow("Could not convert u64 to usize") |
630 | | - )) |
| 642 | + map_first_result!(decode_u64(rest)?, |val| usize::try_from(val) |
| 643 | + .map_err(|_| EncodingError::overflow("Could not convert u64 to usize"))) |
631 | 644 | } |
632 | 645 | }) |
633 | 646 | } |
@@ -695,8 +708,8 @@ fn decode_u64_var(buffer: &[u8]) -> Result<(u64, &[u8]), EncodingError> { |
695 | 708 | let ([first], rest) = take_array::<1>(buffer)?; |
696 | 709 | Ok(match first { |
697 | 710 | x if x < U16_SIGNIFIER => (x.into(), rest), |
698 | | - U16_SIGNIFIER => map_first!(decode_u16(rest)?, |x: u16| Ok(x.into())), |
699 | | - U32_SIGNIFIER => map_first!(decode_u32(rest)?, |x: u32| Ok(x.into())), |
| 711 | + U16_SIGNIFIER => map_first!(decode_u16(rest)?, |x: u16| x.into()), |
| 712 | + U32_SIGNIFIER => map_first!(decode_u32(rest)?, |x: u32| x.into()), |
700 | 713 | _ => decode_u64(rest)?, |
701 | 714 | }) |
702 | 715 | } |
@@ -1242,4 +1255,12 @@ mod test { |
1242 | 1255 |
|
1243 | 1256 | Ok(()) |
1244 | 1257 | } |
| 1258 | + |
| 1259 | + #[test] |
| 1260 | + fn addr_6() -> Result<(), Box<dyn std::error::Error>> { |
| 1261 | + let addr: Ipv6Addr = "1:2:3::1".parse()?; |
| 1262 | + let buff = addr.to_encoded_bytes()?.to_vec(); |
| 1263 | + assert_eq!(buff, vec![0, 1, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); |
| 1264 | + Ok(()) |
| 1265 | + } |
1245 | 1266 | } |
0 commit comments