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::{Deserialize, Serialize};
use serde::de::{self, Deserializer, Visitor};
use serde::ser::Serializer;
use specifications::address::Address;
pub use crate::spec::YamlError as Error;
use crate::errors::ProxyProtocolParseError;
use crate::spec::YamlConfig;
#[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> YamlConfig<'de> for ProxyConfig {}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ForwardConfig {
pub address : Address,
pub protocol : ProxyProtocol,
}