use std::fmt;
use std::net::SocketAddr;
use std::ops::Deref;
use std::str::FromStr;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Protocol {
Udp,
Tcp,
SslTcp,
Tls,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum TcpType {
Active,
Passive,
So,
}
impl fmt::Display for TcpType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let str = match self {
Self::Active => "active",
Self::Passive => "passive",
Self::So => "so",
};
f.write_str(str)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseTcpTypeError;
impl fmt::Display for ParseTcpTypeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("invalid TCP type (expected: active, passive, or so)")
}
}
impl std::error::Error for ParseTcpTypeError {}
impl FromStr for TcpType {
type Err = ParseTcpTypeError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
_ if s.eq_ignore_ascii_case("active") => Ok(Self::Active),
_ if s.eq_ignore_ascii_case("passive") => Ok(Self::Passive),
_ if s.eq_ignore_ascii_case("so") => Ok(Self::So),
_ => Err(ParseTcpTypeError),
}
}
}
impl TryFrom<&str> for Protocol {
type Error = ();
fn try_from(proto: &str) -> Result<Self, Self::Error> {
let proto = proto.to_lowercase();
match proto.as_str() {
"udp" => Ok(Protocol::Udp),
"tcp" => Ok(Protocol::Tcp),
"ssltcp" => Ok(Protocol::SslTcp),
"tls" => Ok(Protocol::Tls),
_ => Err(()),
}
}
}
impl From<Protocol> for &str {
fn from(proto: Protocol) -> Self {
match proto {
Protocol::Udp => "udp",
Protocol::Tcp => "tcp",
Protocol::SslTcp => "ssltcp",
Protocol::Tls => "tls",
}
}
}
impl fmt::Display for Protocol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let x: &str = (*self).into();
write!(f, "{}", x)
}
}
#[derive(Serialize, Deserialize)]
pub struct Transmit {
pub proto: Protocol,
pub source: SocketAddr,
pub destination: SocketAddr,
pub contents: DatagramSend,
}
impl fmt::Debug for Transmit {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Transmit")
.field("proto", &self.proto)
.field("source", &self.source)
.field("destination", &self.destination)
.field("len", &self.contents.len())
.finish()
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct DatagramSend(Vec<u8>);
impl From<Vec<u8>> for DatagramSend {
fn from(value: Vec<u8>) -> Self {
DatagramSend(value)
}
}
impl From<DatagramSend> for Vec<u8> {
fn from(value: DatagramSend) -> Self {
value.0
}
}
impl Deref for DatagramSend {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}