use anyhow::Result;
pub fn parse_target(input: &str) -> Result<ParsedTarget> {
use url::Url;
if input.starts_with("ws://") || input.starts_with("wss://") {
let url = Url::parse(input)?;
let host = url.host_str()
.ok_or_else(|| anyhow::anyhow!("Missing host in URL"))?
.to_string();
let port = url.port_or_known_default()
.ok_or_else(|| anyhow::anyhow!("Cannot determine port"))?;
return Ok(ParsedTarget {
url: input.to_string(),
host,
port,
});
}
let (host, port) = if let Some((h, p)) = input.split_once(':') {
let port = p.parse::<u16>()?;
(h.to_string(), port)
} else {
(input.to_string(), 18789)
};
let url = format!("ws://{}:{}", host, port);
Ok(ParsedTarget {
url,
host,
port,
})
}
#[derive(Debug, Clone, PartialEq)]
pub struct ParsedTarget {
pub url: String,
pub host: String,
pub port: u16,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_simple_domain() {
let target = parse_target("example.com").unwrap();
assert_eq!(target.url, "ws://example.com:18789");
assert_eq!(target.host, "example.com");
assert_eq!(target.port, 18789);
}
#[test]
fn test_parse_ip_address() {
let target = parse_target("192.168.1.100").unwrap();
assert_eq!(target.url, "ws://192.168.1.100:18789");
assert_eq!(target.host, "192.168.1.100");
assert_eq!(target.port, 18789);
}
#[test]
fn test_parse_domain_with_custom_port() {
let target = parse_target("example.com:9999").unwrap();
assert_eq!(target.url, "ws://example.com:9999");
assert_eq!(target.host, "example.com");
assert_eq!(target.port, 9999);
}
#[test]
fn test_parse_explicit_ws_url() {
let target = parse_target("ws://example.com:18789").unwrap();
assert_eq!(target.url, "ws://example.com:18789");
assert_eq!(target.host, "example.com");
assert_eq!(target.port, 18789);
}
#[test]
fn test_parse_explicit_wss_url() {
let target = parse_target("wss://secure.example.com:443").unwrap();
assert_eq!(target.url, "wss://secure.example.com:443");
assert_eq!(target.host, "secure.example.com");
assert_eq!(target.port, 443);
}
#[test]
fn test_parse_localhost() {
let target = parse_target("localhost").unwrap();
assert_eq!(target.url, "ws://localhost:18789");
assert_eq!(target.host, "localhost");
assert_eq!(target.port, 18789);
}
#[test]
fn test_parse_localhost_with_port() {
let target = parse_target("localhost:8080").unwrap();
assert_eq!(target.url, "ws://localhost:8080");
assert_eq!(target.host, "localhost");
assert_eq!(target.port, 8080);
}
#[test]
fn test_parse_subdomain() {
let target = parse_target("gateway.internal.corp.com").unwrap();
assert_eq!(target.url, "ws://gateway.internal.corp.com:18789");
assert_eq!(target.host, "gateway.internal.corp.com");
assert_eq!(target.port, 18789);
}
#[test]
fn test_invalid_port_returns_error() {
let result = parse_target("example.com:99999");
assert!(result.is_err());
}
#[test]
fn test_invalid_url_returns_error() {
let result = parse_target("ws://");
assert!(result.is_err());
}
}