use core::{
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
time::Duration,
};
use std::num::NonZeroUsize;
use varing::{Varint, decode_duration, encode_duration_to, encoded_duration_len};
use crate::{Data, DataRef, DecodeError, EncodeError, WireType};
const IPV4_ADDR_LEN: usize = 4;
const IPV6_ADDR_LEN: usize = 16;
impl<'a> DataRef<'a, Self> for Ipv4Addr {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
if src.len() < IPV4_ADDR_LEN {
return Err(DecodeError::buffer_underflow());
}
let octets: [u8; IPV4_ADDR_LEN] = src[..IPV4_ADDR_LEN].try_into().unwrap();
Ok((IPV4_ADDR_LEN, Self::from(octets)))
}
}
impl Data for Ipv4Addr {
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
#[inline]
fn encoded_len(&self) -> usize {
IPV4_ADDR_LEN
}
#[inline]
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
if buf.len() < IPV4_ADDR_LEN {
return Err(EncodeError::insufficient_buffer(IPV4_ADDR_LEN, buf.len()));
}
buf[..IPV4_ADDR_LEN].copy_from_slice(&self.octets());
Ok(IPV4_ADDR_LEN)
}
}
impl<'a> DataRef<'a, Self> for Ipv6Addr {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
if src.len() < IPV6_ADDR_LEN {
return Err(DecodeError::buffer_underflow());
}
let octets: [u8; IPV6_ADDR_LEN] = src[..IPV6_ADDR_LEN].try_into().unwrap();
Ok((IPV6_ADDR_LEN, Self::from(octets)))
}
}
impl Data for Ipv6Addr {
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
#[inline]
fn encoded_len(&self) -> usize {
IPV6_ADDR_LEN
}
#[inline]
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
if buf.len() < IPV6_ADDR_LEN {
return Err(EncodeError::insufficient_buffer(IPV6_ADDR_LEN, buf.len()));
}
buf[..IPV6_ADDR_LEN].copy_from_slice(&self.octets());
Ok(IPV6_ADDR_LEN)
}
}
impl<'a> DataRef<'a, Self> for IpAddr {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
let buf_len = src.len();
if buf_len < 1 {
return Err(DecodeError::buffer_underflow());
}
match src[0] {
0 => {
let (len, addr) = <Ipv4Addr as DataRef<Ipv4Addr>>::decode(&src[1..])?;
Ok((len + 1, IpAddr::V4(addr)))
}
1 => {
let (len, addr) = <Ipv6Addr as DataRef<Ipv6Addr>>::decode(&src[1..])?;
Ok((len + 1, IpAddr::V6(addr)))
}
val => Err(DecodeError::unknown_tag("IpAddr", val)),
}
}
}
impl Data for IpAddr {
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
#[inline]
fn encoded_len(&self) -> usize {
1 + match self {
IpAddr::V4(addr) => addr.encoded_len(),
IpAddr::V6(addr) => addr.encoded_len(),
}
}
#[inline]
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
match self {
Self::V4(addr) => {
const V4_REQUIRED: usize = 1 + IPV4_ADDR_LEN;
if buf.len() < V4_REQUIRED {
return Err(EncodeError::insufficient_buffer(V4_REQUIRED, buf.len()));
}
buf[0] = 0;
buf[1..V4_REQUIRED].copy_from_slice(&addr.octets());
Ok(V4_REQUIRED)
}
Self::V6(addr) => {
const V6_REQUIRED: usize = 1 + IPV6_ADDR_LEN;
if buf.len() < V6_REQUIRED {
return Err(EncodeError::insufficient_buffer(V6_REQUIRED, buf.len()));
}
buf[0] = 1;
buf[1..V6_REQUIRED].copy_from_slice(&addr.octets());
Ok(V6_REQUIRED)
}
}
}
}
impl<'a> DataRef<'a, Self> for SocketAddrV4 {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError>
where
Self: Sized,
{
const V4_REQUIRED: usize = IPV4_ADDR_LEN + 2;
let buf_len = src.len();
if buf_len < V4_REQUIRED {
return Err(DecodeError::buffer_underflow());
}
let (ip_len, ip) = <Ipv4Addr as DataRef<Ipv4Addr>>::decode(src)?;
let port = u16::from_be_bytes(src[ip_len..ip_len + 2].try_into().unwrap());
Ok((V4_REQUIRED, SocketAddrV4::new(ip, port)))
}
}
impl Data for SocketAddrV4 {
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
#[inline]
fn encoded_len(&self) -> usize {
IPV4_ADDR_LEN + 2
}
#[inline]
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
const V4_REQUIRED: usize = IPV4_ADDR_LEN + 2;
if buf.len() < V4_REQUIRED {
return Err(EncodeError::insufficient_buffer(V4_REQUIRED, buf.len()));
}
buf[..IPV4_ADDR_LEN].copy_from_slice(&self.ip().octets());
buf[IPV4_ADDR_LEN..V4_REQUIRED].copy_from_slice(&self.port().to_be_bytes());
Ok(V4_REQUIRED)
}
}
impl<'a> DataRef<'a, Self> for SocketAddrV6 {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError>
where
Self: Sized,
{
const V6_REQUIRED: usize = IPV6_ADDR_LEN + 2;
let buf_len = src.len();
if buf_len < V6_REQUIRED {
return Err(DecodeError::buffer_underflow());
}
let (ip_len, ip) = <Ipv6Addr as DataRef<Ipv6Addr>>::decode(src)?;
let port = u16::from_be_bytes(src[ip_len..ip_len + 2].try_into().unwrap());
Ok((V6_REQUIRED, SocketAddrV6::new(ip, port, 0, 0)))
}
}
impl Data for SocketAddrV6 {
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
#[inline]
fn encoded_len(&self) -> usize {
IPV6_ADDR_LEN + 2
}
#[inline]
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
const V6_REQUIRED: usize = IPV6_ADDR_LEN + 2;
if buf.len() < V6_REQUIRED {
return Err(EncodeError::insufficient_buffer(V6_REQUIRED, buf.len()));
}
buf[..IPV6_ADDR_LEN].copy_from_slice(&self.ip().octets());
buf[IPV6_ADDR_LEN..V6_REQUIRED].copy_from_slice(&self.port().to_be_bytes());
Ok(V6_REQUIRED)
}
}
impl<'a> DataRef<'a, Self> for SocketAddr {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError>
where
Self: Sized,
{
let buf_len = src.len();
if buf_len < 1 {
return Err(DecodeError::buffer_underflow());
}
match src[0] {
0 => {
let (len, addr) = <SocketAddrV4 as DataRef<SocketAddrV4>>::decode(&src[1..])?;
Ok((len + 1, SocketAddr::V4(addr)))
}
1 => {
let (len, addr) = <SocketAddrV6 as DataRef<SocketAddrV6>>::decode(&src[1..])?;
Ok((len + 1, SocketAddr::V6(addr)))
}
val => Err(DecodeError::unknown_tag("SocketAddr", val)),
}
}
}
impl Data for SocketAddr {
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
#[inline]
fn encoded_len(&self) -> usize {
1 + match self {
SocketAddr::V4(addr) => addr.encoded_len(),
SocketAddr::V6(addr) => addr.encoded_len(),
}
}
#[inline]
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
match self {
Self::V4(addr) => {
const V4_REQUIRED: usize = 1 + IPV4_ADDR_LEN + 2;
if buf.len() < V4_REQUIRED {
return Err(EncodeError::insufficient_buffer(V4_REQUIRED, buf.len()));
}
buf[0] = 0;
let len = addr.encode(&mut buf[1..])?;
Ok(len + 1)
}
Self::V6(addr) => {
const V6_REQUIRED: usize = 1 + IPV6_ADDR_LEN + 2;
if buf.len() < V6_REQUIRED {
return Err(EncodeError::insufficient_buffer(V6_REQUIRED, buf.len()));
}
buf[0] = 1;
let len = addr.encode(&mut buf[1..])?;
Ok(len + 1)
}
}
}
}
macro_rules! impl_primitives {
(@integer $($ty:ident), +$(,)?) => {
$(
impl<'a> DataRef<'a, Self> for $ty {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
Varint::decode(src).map(|(read, val)| (read.get(), val)).map_err(Into::into)
}
}
impl Data for $ty {
const WIRE_TYPE: WireType = WireType::Varint;
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
fn encoded_len(&self) -> usize {
Varint::encoded_len(self).get()
}
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
Varint::encode(self, buf).map(::core::num::NonZeroUsize::get).map_err(Into::into)
}
}
)*
};
(@float $($ty:literal), +$(,)?) => {
paste::paste! {
$(
impl<'a> DataRef<'a, Self> for [< f $ty >] {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
const SIZE: usize = core::mem::size_of::<[< f $ty >]>();
if src.len() < SIZE {
return Err(DecodeError::buffer_underflow());
}
let mut bytes = [0; SIZE];
bytes.copy_from_slice(&src[..SIZE]);
Ok((SIZE, Self::from_le_bytes(bytes)))
}
}
impl Data for [< f $ty >] {
const WIRE_TYPE: WireType = WireType:: [< Fixed $ty >];
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
fn encoded_len(&self) -> usize {
core::mem::size_of::<[< f $ty >]>()
}
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
const SIZE: usize = core::mem::size_of::<[< f $ty >]>();
if buf.len() < SIZE {
return Err(EncodeError::insufficient_buffer(
SIZE, buf.len(),
));
}
buf[..SIZE].copy_from_slice(&self.to_le_bytes());
Ok(SIZE)
}
}
)*
}
};
(@as_u8 $($ty:ident), +$(,)?) => {
$(
impl<'a> DataRef<'a, Self> for $ty {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
<u8 as DataRef<u8>>::decode(src).map(|(bytes_read, value)| (bytes_read, value as $ty))
}
}
impl Data for $ty {
const WIRE_TYPE: WireType = WireType::Byte;
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
fn encoded_len(&self) -> usize {
<u8 as Data>::encoded_len(&(*self as u8))
}
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
<u8 as Data>::encode(&(*self as u8), buf)
}
}
)*
};
(@wrapper $($wrapper:ty), +$(,)?) => {
$(
impl<'a, T> DataRef<'a, $wrapper> for T::Ref<'a>
where
T: Data,
{
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
let (bytes_read, value) = T::Ref::decode(src)?;
Ok((bytes_read, value))
}
}
impl<T> Data for $wrapper
where
T: Data,
{
const WIRE_TYPE: WireType = T::WIRE_TYPE;
type Ref<'a> = <T as Data>::Ref<'a>;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
T::from_ref(val).map(From::from)
}
fn encoded_len(&self) -> usize {
T::encoded_len(&**self)
}
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
T::encode(&**self, buf)
}
}
)*
};
}
impl_primitives!(@integer u16, u32, u64, u128, i16, i32, i64, i128);
impl_primitives!(@float 32, 64);
impl_primitives!(@as_u8 i8);
#[cfg(any(feature = "std", feature = "alloc"))]
impl_primitives!(@wrapper std::sync::Arc<T>, std::boxed::Box<T>, triomphe::Arc<T>);
impl<'a> DataRef<'a, Self> for char {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
let (bytes_read, value) = Varint::decode(src)?;
Ok((
bytes_read.get(),
char::from_u32(value).ok_or_else(|| DecodeError::custom("invalid character value"))?,
))
}
}
impl Data for char {
const WIRE_TYPE: WireType = WireType::Varint;
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
fn encoded_len(&self) -> usize {
Varint::encoded_len(&(*self as u32)).get()
}
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
Varint::encode(&(*self as u32), buf)
.map(NonZeroUsize::get)
.map_err(Into::into)
}
}
impl<'a> DataRef<'a, Self> for u8 {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
if src.is_empty() {
return Err(DecodeError::buffer_underflow());
}
Ok((1, src[0]))
}
}
impl Data for u8 {
const WIRE_TYPE: WireType = WireType::Byte;
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
fn encoded_len(&self) -> usize {
1
}
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
if buf.is_empty() {
return Err(EncodeError::insufficient_buffer(1, 0));
}
buf[0] = *self;
Ok(1)
}
}
impl<'a> DataRef<'a, Self> for bool {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
if src.is_empty() {
return Err(DecodeError::buffer_underflow());
}
Ok((1, src[0] != 0))
}
}
impl Data for bool {
const WIRE_TYPE: WireType = WireType::Byte;
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
fn encoded_len(&self) -> usize {
1
}
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
<u8 as Data>::encode(&(*self as u8), buf)
}
}
impl<'a> DataRef<'a, Self> for Duration {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError> {
decode_duration(src)
.map(|(read, val)| (read.get(), val))
.map_err(|_| DecodeError::custom("invalid duration"))
}
}
impl Data for Duration {
const WIRE_TYPE: WireType = WireType::Varint;
type Ref<'a> = Self;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
Ok(val)
}
fn encoded_len(&self) -> usize {
encoded_duration_len(self).get()
}
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
encode_duration_to(self, buf)
.map(NonZeroUsize::get)
.map_err(Into::into)
}
}