use std::fmt;
use std::net::SocketAddr;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TlsInfo {
pub protocol_version: Option<String>,
pub server_name: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ConnectionInfo {
pub local_addr: SocketAddr,
pub remote_addr: SocketAddr,
pub scheme: Scheme,
pub tls: Option<TlsInfo>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Scheme {
Http,
Https,
}
impl Scheme {
pub fn as_str(&self) -> &'static str {
match self {
Self::Http => "http",
Self::Https => "https",
}
}
}
impl fmt::Display for Scheme {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl fmt::Display for TlsInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "TLS")?;
if let Some(ref v) = self.protocol_version {
write!(f, " {v}")?;
}
if let Some(ref n) = self.server_name {
write!(f, " SNI={n}")?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn scheme_as_str() {
assert_eq!(Scheme::Http.as_str(), "http");
assert_eq!(Scheme::Https.as_str(), "https");
}
#[test]
fn scheme_display() {
assert_eq!(format!("{}", Scheme::Http), "http");
assert_eq!(format!("{}", Scheme::Https), "https");
}
#[test]
fn tls_info_display() {
let info = TlsInfo {
protocol_version: Some("TLSv1.3".to_string()),
server_name: Some("example.com".to_string()),
};
let display = format!("{info}");
assert!(display.contains("TLSv1.3"));
assert!(display.contains("example.com"));
}
#[test]
fn tls_info_minimal() {
let info = TlsInfo {
protocol_version: None,
server_name: None,
};
assert_eq!(format!("{info}"), "TLS");
}
#[test]
fn connection_info_equality() {
let a = ConnectionInfo {
local_addr: "127.0.0.1:8000".parse().unwrap(),
remote_addr: "127.0.0.1:12345".parse().unwrap(),
scheme: Scheme::Http,
tls: None,
};
let b = ConnectionInfo {
local_addr: "127.0.0.1:8000".parse().unwrap(),
remote_addr: "127.0.0.1:12345".parse().unwrap(),
scheme: Scheme::Http,
tls: None,
};
assert_eq!(a, b);
}
#[test]
fn connection_info_with_tls() {
let info = ConnectionInfo {
local_addr: "0.0.0.0:443".parse().unwrap(),
remote_addr: "10.0.0.1:54321".parse().unwrap(),
scheme: Scheme::Https,
tls: Some(TlsInfo {
protocol_version: Some("TLSv1.3".to_string()),
server_name: Some("example.com".to_string()),
}),
};
assert_eq!(info.scheme, Scheme::Https);
assert!(info.tls.is_some());
}
}