use std::error::Error;
use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, PartialEq)]
pub enum Family {
Inet,
Inet6,
IpX,
Can,
}
impl fmt::Display for Family {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let family_str = match self {
Family::Inet => "inet",
Family::Inet6 => "inet6",
Family::IpX => "ipx",
Family::Can => "can",
};
write!(f, "{}", family_str)
}
}
impl FromStr for Family {
type Err = FamilyParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"inet" => Ok(Family::Inet),
"inet6" => Ok(Family::Inet6),
"ipx" => Ok(Family::IpX),
"can" => Ok(Family::Can),
_ => Err(FamilyParseError(s.to_string())),
}
}
}
#[derive(Debug, Clone)]
pub struct FamilyParseError(pub String);
impl fmt::Display for FamilyParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Invalid family: {}", self.0)
}
}
impl Error for FamilyParseError {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_family_from_str() {
assert_eq!(Family::from_str("inet").unwrap(), Family::Inet);
assert_eq!(Family::from_str("inet6").unwrap(), Family::Inet6);
assert_eq!(Family::from_str("ipx").unwrap(), Family::IpX);
assert_eq!(Family::from_str("can").unwrap(), Family::Can);
}
#[test]
fn test_family_from_str_invalid() {
let err = Family::from_str("invalid").unwrap_err();
assert_eq!(err.0, "invalid");
assert_eq!(err.to_string(), "Invalid family: invalid");
}
#[test]
fn test_family_display() {
assert_eq!(Family::Inet.to_string(), "inet");
assert_eq!(Family::Inet6.to_string(), "inet6");
assert_eq!(Family::IpX.to_string(), "ipx");
assert_eq!(Family::Can.to_string(), "can");
}
#[test]
fn test_family_roundtrip() {
for family in [Family::Inet, Family::Inet6, Family::IpX, Family::Can] {
let s = family.to_string();
let parsed: Family = s.parse().unwrap();
assert_eq!(parsed, family);
}
}
}