use std::collections::HashMap;
use std::fmt::{Display, Formatter, Result as FResult};
use std::ops::RangeInclusive;
use std::str::FromStr;
use enum_debug::EnumDebug;
use serde::de::{self, Deserializer, Visitor};
use serde::ser::Serializer;
use serde::{Deserialize, Serialize};
use specifications::address::Address;
use crate::errors::ProxyProtocolParseError;
pub use crate::info::YamlError as Error;
use crate::info::YamlInfo;
#[derive(Clone, Copy, Debug, EnumDebug, Eq, Hash, PartialEq)]
pub enum ProxyProtocol {
Socks5,
Socks6,
}
impl Display for ProxyProtocol {
fn fmt(&self, f: &mut Formatter<'_>) -> FResult {
use ProxyProtocol::*;
match self {
Socks5 => write!(f, "SOCKS5"),
Socks6 => write!(f, "SOCKS6"),
}
}
}
impl FromStr for ProxyProtocol {
type Err = ProxyProtocolParseError;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"socks5" => Ok(Self::Socks5),
"socks6" => Ok(Self::Socks6),
_ => Err(ProxyProtocolParseError::UnknownProtocol { raw: s.into() }),
}
}
}
impl Serialize for ProxyProtocol {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
impl<'de> Deserialize<'de> for ProxyProtocol {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ProxyProtocolVisitor;
impl<'de> Visitor<'de> for ProxyProtocolVisitor {
type Value = ProxyProtocol;
fn expecting(&self, f: &mut Formatter<'_>) -> FResult { write!(f, "a proxy protocol identifier") }
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
match ProxyProtocol::from_str(v) {
Ok(prot) => Ok(prot),
Err(err) => Err(E::custom(err)),
}
}
}
deserializer.deserialize_str(ProxyProtocolVisitor)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ProxyConfig {
pub outgoing_range: RangeInclusive<u16>,
#[serde(default = "HashMap::new")]
pub incoming: HashMap<u16, Address>,
pub forward: Option<ForwardConfig>,
}
impl Default for ProxyConfig {
fn default() -> Self {
Self {
outgoing_range: 4200..=4299,
incoming: HashMap::new(),
forward: None,
}
}
}
impl<'de> YamlInfo<'de> for ProxyConfig {}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ForwardConfig {
pub address: Address,
pub protocol: ProxyProtocol,
}