length_delimited/
net.rs

1use core::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
2
3use dbutils::{
4  error::{IncompleteBuffer, InsufficientBuffer},
5  leb128::DecodeVarintError,
6};
7
8use super::{LengthDelimitedDecoder, LengthDelimitedEncoder};
9
10macro_rules! net_impl {
11  (@ip $($ty:ident($inner:ident)), + $(,)?) => {
12    $(
13      impl LengthDelimitedEncoder for $ty {
14        type Error = InsufficientBuffer;
15
16        fn encoded_len(&self) -> usize {
17          self.to_bits().encoded_len()
18        }
19
20        fn encoded_length_delimited_len(&self) -> usize {
21          Self::encoded_len(self)
22        }
23
24        fn encode_length_delimited(&self, buf: &mut [u8]) -> Result<usize, Self::Error> {
25          Self::encode(self, buf)
26        }
27
28        fn encode(&self, buf: &mut [u8]) -> Result<usize, Self::Error> {
29          self.to_bits().encode(buf)
30        }
31      }
32
33      impl LengthDelimitedDecoder for $ty {
34        type Error = DecodeVarintError;
35
36        fn decode(src: &[u8]) -> Result<(usize, Self), Self::Error>
37        where
38          Self: Sized,
39        {
40          let (read, inner) = <$inner as LengthDelimitedDecoder>::decode(src)?;
41          Ok((read, $ty::from_bits(inner)))
42        }
43
44        fn decode_length_delimited(src: &[u8]) -> Result<(usize, Self), Self::Error>
45        where
46          Self: Sized,
47        {
48          Self::decode(src)
49        }
50      }
51    )*
52  };
53  (@sock $($ty:ident($inner:ident $(, $($defaults:literal), +$(,)? )? )),+$(,)?) => {
54    $(
55      impl LengthDelimitedEncoder for $ty {
56        type Error = InsufficientBuffer;
57
58        fn encoded_len(&self) -> usize {
59          self.ip().encoded_len() + 2
60        }
61
62        fn encoded_length_delimited_len(&self) -> usize {
63          Self::encoded_len(self)
64        }
65
66        fn encode_length_delimited(&self, buf: &mut [u8]) -> Result<usize, Self::Error> {
67          Self::encode(self, buf)
68        }
69
70        fn encode(&self, buf: &mut [u8]) -> Result<usize, Self::Error> {
71          let encoded_len = self.encoded_len();
72          if buf.len() < encoded_len {
73            return Err(InsufficientBuffer::with_information(encoded_len as u64, buf.len() as u64));
74          }
75
76          self.ip().encode(buf)?;
77          let port = self.port();
78          buf[encoded_len - 2..encoded_len].copy_from_slice(&port.to_le_bytes());
79          Ok(encoded_len)
80        }
81      }
82
83      impl LengthDelimitedDecoder for $ty {
84        type Error = DecodeSocketAddrError;
85
86        fn decode(src: &[u8]) -> Result<(usize, Self), Self::Error>
87        where
88          Self: Sized,
89        {
90          let (read, ip) = $inner::decode(src)?;
91          if read + 2 > src.len() {
92            return Err(Self::Error::IncompleteBuffer(IncompleteBuffer::with_information((read + 2) as u64, src.len() as u64)));
93          }
94
95          let port = u16::from_le_bytes([src[read], src[read + 1]]);
96          Ok((read + 2, Self::new(ip, port $(, $($defaults),* )? )))
97        }
98
99        fn decode_length_delimited(src: &[u8]) -> Result<(usize, Self), Self::Error>
100        where
101          Self: Sized,
102        {
103          Self::decode(src)
104        }
105      }
106    )*
107  }
108}
109
110net_impl!(@ip Ipv4Addr(u32), Ipv6Addr(u128),);
111net_impl!(@sock SocketAddrV4(Ipv4Addr), SocketAddrV6(Ipv6Addr, 0, 0));
112
113/// An error that can occur when decoding a `SocketAddrV4` or `SocketAddrV6` from bytes.
114#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
115pub enum DecodeSocketAddrError {
116  /// The buffer is incomplete.
117  #[error(transparent)]
118  IncompleteBuffer(#[from] IncompleteBuffer),
119  /// The IP address could not be decoded.
120  #[error("value is not a valid IP address")]
121  InvalidIpAddress,
122}
123
124impl From<DecodeVarintError> for DecodeSocketAddrError {
125  fn from(e: DecodeVarintError) -> Self {
126    match e {
127      DecodeVarintError::Underflow => {
128        DecodeSocketAddrError::IncompleteBuffer(IncompleteBuffer::new())
129      }
130      _ => DecodeSocketAddrError::InvalidIpAddress,
131    }
132  }
133}