wtx 0.43.1

A collection of different transport implementations and related tools focused primarily on web technologies.
Documentation
use crate::{
  codec::{Decode, Encode},
  database::{
    Typed,
    client::postgres::{DecodeWrapper, EncodeWrapper, Postgres, PostgresError, Ty},
  },
};
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};

impl<'exec, E> Decode<'exec, Postgres<E>> for IpAddr
where
  E: From<crate::Error>,
{
  #[inline]
  fn decode(dw: &mut DecodeWrapper<'exec, '_>) -> Result<Self, E> {
    Ok(match dw.bytes() {
      [2, ..] => IpAddr::V4(Ipv4Addr::decode(dw)?),
      [3, ..] => IpAddr::V6(Ipv6Addr::decode(dw)?),
      _ => return Err(E::from(PostgresError::InvalidIpFormat.into())),
    })
  }
}
impl<E> Encode<Postgres<E>> for IpAddr
where
  E: From<crate::Error>,
{
  #[inline]
  fn encode(&self, ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
    match self {
      IpAddr::V4(ipv4_addr) => ipv4_addr.encode(ew),
      IpAddr::V6(ipv6_addr) => ipv6_addr.encode(ew),
    }
  }
}
impl<E> Typed<Postgres<E>> for IpAddr
where
  E: From<crate::Error>,
{
  #[inline]
  fn runtime_ty(&self) -> Option<Ty> {
    <Self as Typed<Postgres<E>>>::static_ty()
  }

  #[inline]
  fn static_ty() -> Option<Ty> {
    Some(Ty::Inet)
  }
}
test!(ipaddr_v4, IpAddr, IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)));
test!(ipaddr_v6, IpAddr, IpAddr::V6(Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)));

impl<'exec, E> Decode<'exec, Postgres<E>> for Ipv4Addr
where
  E: From<crate::Error>,
{
  #[inline]
  fn decode(dw: &mut DecodeWrapper<'exec, '_>) -> Result<Self, E> {
    let [2, 32, 0, 4, e, f, g, h] = dw.bytes() else {
      return Err(E::from(PostgresError::InvalidIpFormat.into()));
    };
    Ok(Ipv4Addr::from([*e, *f, *g, *h]))
  }
}
impl<E> Encode<Postgres<E>> for Ipv4Addr
where
  E: From<crate::Error>,
{
  #[inline]
  fn encode(&self, ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
    ew.buffer().extend_from_slices([&[2, 32, 0, 4][..], &self.octets()])?;
    Ok(())
  }
}
impl<E> Typed<Postgres<E>> for Ipv4Addr
where
  E: From<crate::Error>,
{
  #[inline]
  fn runtime_ty(&self) -> Option<Ty> {
    <Self as Typed<Postgres<E>>>::static_ty()
  }

  #[inline]
  fn static_ty() -> Option<Ty> {
    Some(Ty::Inet)
  }
}
test!(ipv4, Ipv4Addr, Ipv4Addr::new(1, 2, 3, 4));

impl<'exec, E> Decode<'exec, Postgres<E>> for Ipv6Addr
where
  E: From<crate::Error>,
{
  #[inline]
  fn decode(dw: &mut DecodeWrapper<'exec, '_>) -> Result<Self, E> {
    let [3, 128, 0, 16, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t] = dw.bytes() else {
      return Err(E::from(PostgresError::InvalidIpFormat.into()));
    };
    Ok(Ipv6Addr::from([*e, *f, *g, *h, *i, *j, *k, *l, *m, *n, *o, *p, *q, *r, *s, *t]))
  }
}
impl<E> Encode<Postgres<E>> for Ipv6Addr
where
  E: From<crate::Error>,
{
  #[inline]
  fn encode(&self, ew: &mut EncodeWrapper<'_, '_>) -> Result<(), E> {
    ew.buffer().extend_from_slices([&[3, 128, 0, 16][..], &self.octets()])?;
    Ok(())
  }
}
impl<E> Typed<Postgres<E>> for Ipv6Addr
where
  E: From<crate::Error>,
{
  #[inline]
  fn runtime_ty(&self) -> Option<Ty> {
    <Self as Typed<Postgres<E>>>::static_ty()
  }

  #[inline]
  fn static_ty() -> Option<Ty> {
    Some(Ty::Inet)
  }
}
test!(ipv6, Ipv6Addr, Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8));