use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum HostStatus {
Unknown,
Down,
Filtered,
Up,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum StatusProtocol {
Arp,
IcmpEcho,
TcpSyn,
Udp,
Custom(Arc<str>),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StatusReason {
pub protocol: StatusProtocol,
pub details: Option<Arc<str>>,
}
impl StatusReason {
pub fn new(protocol: StatusProtocol, details: impl Into<Arc<str>>) -> Self {
Self {
protocol,
details: Some(details.into()),
}
}
pub fn basic(protocol: StatusProtocol) -> Self {
Self {
protocol,
details: None,
}
}
}
impl HostStatus {
#[inline]
pub fn is_up(&self) -> bool {
matches!(self, HostStatus::Up)
}
#[inline]
pub fn is_down(&self) -> bool {
matches!(self, HostStatus::Down)
}
#[inline]
pub fn is_alive(&self) -> bool {
matches!(self, HostStatus::Up | HostStatus::Filtered)
}
}
impl std::fmt::Display for HostStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
HostStatus::Unknown => write!(f, "Unknown"),
HostStatus::Down => write!(f, "Down"),
HostStatus::Filtered => write!(f, "Filtered"),
HostStatus::Up => write!(f, "Up"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn status_ordering_contract() {
assert!(HostStatus::Unknown < HostStatus::Down);
assert!(HostStatus::Down < HostStatus::Filtered);
assert!(HostStatus::Filtered < HostStatus::Up);
}
#[test]
fn status_alive_semantics() {
assert!(!HostStatus::Unknown.is_alive());
assert!(!HostStatus::Down.is_alive());
assert!(HostStatus::Filtered.is_alive());
assert!(HostStatus::Up.is_alive());
}
#[test]
fn status_display_consistency() {
assert_eq!(HostStatus::Unknown.to_string(), "Unknown");
assert_eq!(HostStatus::Up.to_string(), "Up");
}
#[test]
fn status_reason_ergonomics() {
let reason = StatusReason::new(
StatusProtocol::Custom(Arc::from("dns-probe")),
"Resolved A record successfully",
);
assert_eq!(
reason.protocol,
StatusProtocol::Custom(Arc::from("dns-probe"))
);
assert_eq!(reason.details.as_deref(), Some("Resolved A record successfully"));
}
}