use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
use crate::PrintError;
pub(crate) const DEFAULT_PORT: u16 = 9100;
pub fn resolve_printer_addr(input: &str) -> Result<SocketAddr, PrintError> {
if let Ok(addr) = input.parse::<SocketAddr>() {
return Ok(addr);
}
if let Ok(ip) = input.parse::<IpAddr>() {
return Ok(SocketAddr::new(ip, DEFAULT_PORT));
}
if let Ok(mut addrs) = input.to_socket_addrs()
&& let Some(addr) = addrs.next()
{
return Ok(addr);
}
if let Ok(mut addrs) = (input, DEFAULT_PORT).to_socket_addrs()
&& let Some(addr) = addrs.next()
{
return Ok(addr);
}
Err(PrintError::NoAddressFound(input.to_string()))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn resolves_ipv4_with_explicit_port() {
let addr = resolve_printer_addr("192.168.1.55:9100").unwrap();
assert_eq!(addr.ip().to_string(), "192.168.1.55");
assert_eq!(addr.port(), 9100);
}
#[test]
fn resolves_ipv4_with_custom_port() {
let addr = resolve_printer_addr("10.0.0.1:6101").unwrap();
assert_eq!(addr.ip().to_string(), "10.0.0.1");
assert_eq!(addr.port(), 6101);
}
#[test]
fn defaults_ipv4_to_port_9100_when_port_missing() {
let addr = resolve_printer_addr("192.168.1.55").unwrap();
assert_eq!(addr.ip().to_string(), "192.168.1.55");
assert_eq!(addr.port(), DEFAULT_PORT);
}
#[test]
fn resolves_ipv6_with_explicit_port() {
let addr = resolve_printer_addr("[::1]:9100").unwrap();
assert!(addr.ip().is_loopback());
assert_eq!(addr.port(), 9100);
}
#[test]
fn defaults_ipv6_to_port_9100_when_port_missing() {
let addr = resolve_printer_addr("::1").unwrap();
assert!(addr.ip().is_loopback());
assert_eq!(addr.port(), DEFAULT_PORT);
}
#[test]
fn resolves_localhost_with_explicit_port() {
let addr = resolve_printer_addr("localhost:9100").unwrap();
assert!(addr.ip().is_loopback());
assert_eq!(addr.port(), 9100);
}
#[test]
fn resolves_localhost_with_default_port() {
let addr = resolve_printer_addr("localhost").unwrap();
assert!(addr.ip().is_loopback());
assert_eq!(addr.port(), DEFAULT_PORT);
}
#[test]
fn returns_no_address_found_for_unresolvable_hostname() {
let result = resolve_printer_addr("no-such-host.invalid");
assert!(result.is_err());
match result.unwrap_err() {
PrintError::NoAddressFound(s) => assert_eq!(s, "no-such-host.invalid"),
other => panic!("expected NoAddressFound, got {:?}", other),
}
}
#[test]
fn returns_no_address_found_for_invalid_address_text() {
let result = resolve_printer_addr("not a valid address!!!");
assert!(result.is_err());
match result.unwrap_err() {
PrintError::NoAddressFound(s) => assert_eq!(s, "not a valid address!!!"),
other => panic!("expected NoAddressFound, got {:?}", other),
}
}
}