use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::net::{AddrParseError, IpAddr, SocketAddr, SocketAddrV4, SocketAddrV6};
use std::str::FromStr;
#[derive(Clone, Debug)]
pub enum Address {
Ori(String),
Addr(SocketAddr),
}
impl Address {
pub fn hash_code(&self) -> u64 {
match self {
Address::Ori(ori) => crate::utils::bytes_to_hash_code(ori.as_bytes()),
Address::Addr(addr) => crate::utils::socketaddr_to_hash_code(addr),
}
}
}
impl From<String> for Address {
fn from(ori: String) -> Self {
Address::Ori(ori)
}
}
impl From<&str> for Address {
fn from(ori: &str) -> Self {
Address::Ori(ori.to_string())
}
}
impl From<SocketAddr> for Address {
fn from(addr: SocketAddr) -> Self {
Address::Addr(addr)
}
}
impl<I: Into<IpAddr>> From<(I, u16)> for Address {
fn from(value: (I, u16)) -> Self {
Address::from(SocketAddr::from(value))
}
}
impl From<SocketAddrV4> for Address {
fn from(value: SocketAddrV4) -> Self {
Address::from(SocketAddr::from(value))
}
}
impl From<SocketAddrV6> for Address {
fn from(value: SocketAddrV6) -> Self {
Address::from(SocketAddr::from(value))
}
}
impl FromStr for Address {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let a = SocketAddr::from_str(s)?;
Ok(Address::from(a))
}
}
#[derive(Clone, Debug)]
pub struct BackendState {
id: Option<u32>,
address: Address,
hash_code: u64,
}
impl BackendState {
pub fn new(id: Option<u32>, addr: Address) -> BackendState {
let hash_code = addr.hash_code();
BackendState {
id,
address: addr,
hash_code,
}
}
pub fn id(&self) -> Option<u32> {
self.id.clone()
}
pub fn hash_code(&self) -> u64 {
self.hash_code
}
pub fn get_address(&self) -> &Address {
&self.address
}
}
impl Hash for BackendState {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u64(self.hash_code)
}
}
impl Eq for BackendState {}
impl PartialEq for BackendState {
fn eq(&self, other: &Self) -> bool {
self.hash_code.eq(&other.hash_code)
}
}
impl PartialOrd for BackendState {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.hash_code.partial_cmp(&other.hash_code)
}
}
impl Ord for BackendState {
fn cmp(&self, other: &Self) -> Ordering {
self.hash_code.cmp(&other.hash_code)
}
}
impl From<Address> for BackendState {
fn from(addr: Address) -> Self {
BackendState::new(None, addr)
}
}