use std::fmt; #[derive(Debug)] pub enum AppError { Io(std::io::Error), Parse(std::num::ParseIntError), Custom(String), } impl fmt::Display for AppError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { AppError::Io(e) => write!(f, "IO error: {}", e), AppError::Parse(e) => write!(f, "Parse error: {}", e), AppError::Custom(s) => write!(f, "Error: {}", s), } } } impl From for AppError { fn from(e: std::io::Error) -> Self { AppError::Io(e) } } impl From for AppError { fn from(e: std::num::ParseIntError) -> Self { AppError::Parse(e) } } fn read_port(s: &str) -> Result { let port: i32 = s.trim().parse()?; if port < 1 || port > 65535 { return Err(AppError::Custom(format!("Port {} out of range", port))); } Ok(port as u16) }