use std::{borrow::Cow, net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}};
use crate::{HaProxRes, HapProtoV1, map_error};
pub trait TryIntoSockAddr
{
fn try_into_sock(self) -> HaProxRes<SocketAddr>;
}
impl TryIntoSockAddr for String
{
#[inline]
fn try_into_sock(self) -> HaProxRes<SocketAddr>
{
return self.as_str().try_into_sock();
}
}
impl TryIntoSockAddr for &String
{
fn try_into_sock(self) -> HaProxRes<SocketAddr>
{
return self.as_str().try_into_sock();
}
}
impl TryIntoSockAddr for &str
{
fn try_into_sock(self) -> HaProxRes<SocketAddr>
{
return
self
.parse()
.map_err(|e|
map_error!(ArgumentEinval, "cannot parse string: '{}' to SocketAddr, err: '{}", self, e)
);
}
}
impl<'cow> TryIntoSockAddr for Cow<'cow, str>
{
fn try_into_sock(self) -> HaProxRes<SocketAddr>
{
return self.as_ref().try_into_sock();
}
}
#[derive(Clone, Copy, Debug)]
pub struct ProxyHdrV1;
impl ProxyHdrV1
{
#[inline]
pub
fn new(src: SocketAddr, dst: SocketAddr) -> HaProxRes<HapProtoV1>
{
return Self::new_ipaddr(src.ip(), src.port(), dst.ip(), dst.port());
}
pub
fn from_str<S: TryIntoSockAddr>(src: S, dst: S) -> HaProxRes<HapProtoV1>
{
let src_addr = src.try_into_sock()?;
let dst_addr = dst.try_into_sock()?;
return HapProtoV1::from_ip_port(src_addr.ip(), dst_addr.ip(), src_addr.port(), dst_addr.port());
}
#[inline]
pub
fn new_ipaddr(src_addr: IpAddr, src_port: u16, dst_addr: IpAddr, dst_port: u16) -> HaProxRes<HapProtoV1>
{
return HapProtoV1::from_ip_port( src_addr, dst_addr, src_port, dst_port);
}
#[inline]
pub
fn new_ip4(src_addr: Ipv4Addr, src_port: u16, dst_addr: Ipv4Addr, dst_port: u16) -> HaProxRes<HapProtoV1>
{
return
HapProtoV1::from_ip_port(IpAddr::V4(src_addr), IpAddr::V4(dst_addr), src_port, dst_port);
}
#[inline]
pub
fn new_ip6(src_addr: Ipv6Addr, src_port: u16, dst_addr: Ipv6Addr, dst_port: u16) -> HaProxRes<HapProtoV1>
{
return
HapProtoV1::from_ip_port(IpAddr::V6(src_addr), IpAddr::V6(dst_addr), src_port, dst_port);
}
#[inline]
pub
fn new_unknown() -> HapProtoV1
{
return HapProtoV1::unknown();
}
}
#[cfg(test)]
mod tests_composer
{
use crate::{protocol_v1::protocol_composer::ProxyHdrV1};
#[test]
fn test_from_string()
{
let res =
ProxyHdrV1::from_str("192.168.1.1:333", "127.0.0.1:444")
.unwrap();
assert_eq!(res.to_string(), "PROXY TCP4 192.168.1.1 127.0.0.1 333 444\r\n");
}
#[test]
fn test0()
{
let res =
ProxyHdrV1
::new("192.168.1.1:333".parse().unwrap(), "127.0.0.1:444".parse().unwrap())
.unwrap();
assert_eq!(res.to_string(), "PROXY TCP4 192.168.1.1 127.0.0.1 333 444\r\n");
let res =
ProxyHdrV1
::new("[0acf:5d35:b4c4:731c:2442:2f17:c6f9:5b7f]:333".parse().unwrap(), "[4d7f:8980:38d6:e0c3:7301:70e9:f8ef:e393]:444".parse().unwrap())
.unwrap();
assert_eq!(res.to_string(), "PROXY TCP6 0acf:5d35:b4c4:731c:2442:2f17:c6f9:5b7f 4d7f:8980:38d6:e0c3:7301:70e9:f8ef:e393 333 444\r\n");
}
#[should_panic]
#[test]
fn test1_fail()
{
let _res =
ProxyHdrV1
::new("[0acf:5d35:b4c4:731c:2442:2f17:c6f9:5b7f]:333".parse().unwrap(), "127.0.0.1:444".parse().unwrap())
.unwrap();
}
#[should_panic]
#[test]
fn test2_fail()
{
let _res =
ProxyHdrV1
::new("192.168.1.1:333".parse().unwrap(), "[0acf:5d35:b4c4:731c:2442:2f17:c6f9:5b7f]:333".parse().unwrap())
.unwrap();
}
}