Skip to content

Commit d85add6

Browse files
committed
Use name resolution to address server
1 parent 9072698 commit d85add6

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

.vscode/settings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"notify"
66
],
77
"cSpell.words": [
8+
"Addrs",
89
"adpcm",
910
"buildflags",
1011
"conv",
@@ -30,6 +31,7 @@
3031
"pipewire",
3132
"pulseaudio",
3233
"rodio",
34+
"rsplitn",
3335
"rustup",
3436
"Setname",
3537
"sgid",

src/main.rs

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::{
2-
net::{Ipv4Addr, SocketAddrV4},
3-
str::FromStr,
2+
net::{Ipv4Addr, SocketAddrV4, ToSocketAddrs},
43
sync::{Arc, Mutex, RwLock},
54
time::{Duration, Instant},
65
};
@@ -38,22 +37,24 @@ mod rodio_out;
3837
struct Cli {
3938
#[arg(
4039
short,
40+
long,
4141
name = "SERVER[:PORT]",
4242
value_parser = cli_server_parser,
4343
help = "Connect to the specified server, otherwise use autodiscovery")]
4444
server: Option<SocketAddrV4>,
4545

4646
#[arg(
4747
short = 'o',
48+
long,
4849
name = "OUTPUT_DEVICE",
4950
help = "Output device [default: System default device]"
5051
)]
5152
device: Option<String>,
5253

53-
#[arg(short, help = "List output devices")]
54+
#[arg(short, long, help = "List output devices")]
5455
list: bool,
5556

56-
#[arg(short, default_value = "Vibe", help = "Set the player name")]
57+
#[arg(short, long, default_value = "Vibe", help = "Set the player name")]
5758
name: String,
5859

5960
#[cfg(all(feature = "pulse", feature = "rodio"))]
@@ -76,13 +77,40 @@ struct Cli {
7677
}
7778

7879
fn cli_server_parser(value: &str) -> anyhow::Result<SocketAddrV4> {
79-
match value.split_once(':') {
80-
Some((ip_str, port_str)) if port_str.len() == 0 => {
81-
Ok(SocketAddrV4::new(Ipv4Addr::from_str(ip_str)?, SLIM_PORT))
80+
// Try parsing as SocketAddrV4 directly (ip:port or host:port)
81+
if let Ok(addr) = value.parse::<SocketAddrV4>() {
82+
return Ok(addr);
83+
}
84+
85+
// Try parsing as Ipv4Addr (ip only, no port)
86+
if let Ok(ip) = value.parse::<Ipv4Addr>() {
87+
return Ok(SocketAddrV4::new(ip, SLIM_PORT));
88+
}
89+
90+
// Try parsing as host[:port]
91+
let mut parts = value.rsplitn(2, ':');
92+
let last = parts.next();
93+
let first = parts.next();
94+
95+
let (host, port) = match (first, last) {
96+
(Some(host), Some(port_str)) if port_str.chars().all(|c| c.is_ascii_digit()) => {
97+
let port = port_str.parse::<u16>().unwrap_or(SLIM_PORT);
98+
(host, port)
99+
}
100+
(Some(_), Some(_)) => (value, SLIM_PORT),
101+
(None, Some(host)) => (host, SLIM_PORT),
102+
_ => (value, SLIM_PORT),
103+
};
104+
105+
// Use ToSocketAddrs to resolve host
106+
let addrs = (host, port).to_socket_addrs()?;
107+
for addr in addrs {
108+
if let std::net::SocketAddr::V4(addr_v4) = addr {
109+
return Ok(addr_v4);
82110
}
83-
Some(_) => Ok(value.parse()?),
84-
None => Ok(SocketAddrV4::new(Ipv4Addr::from_str(value)?, SLIM_PORT)),
85111
}
112+
113+
Err(anyhow::anyhow!("Could not resolve server address"))
86114
}
87115

88116
pub struct StreamParams {

0 commit comments

Comments
 (0)