This commit is contained in:
Brandon Thomas committed 2026-10-12 23:31:19 -04:00
commit 765e94e0a1
1 file changed
+42 -13
+42 -13
View File
@@ -303,16 +303,16 @@ fn mcp(args: &[String]) -> Result<(), String> {
while i < args.len() {
match args[i].as_str() {
"--connect" => {
// Optional address argument.
match args.get(i + 1).filter(|a| !a.starts_with("--") && a.contains(':')) {
Some(a) => {
connect = Some(a.clone());
i += 1;
}
None => connect = Some(DEFAULT_ADDR.to_string()),
let (addr, took) = connect_value(args.get(i + 1).map(String::as_str));
connect = Some(addr);
if took {
i += 1;
}
}
a if a.starts_with("--connect=") => connect = Some(a["--connect=".len()..].to_string()),
a if a.starts_with("--connect=") => {
let (addr, _) = connect_value(Some(&a["--connect=".len()..]));
connect = Some(addr);
}
"--headless" => connect = None,
"--demo" => demo = true,
"--compact" => compact = true,
@@ -525,14 +525,17 @@ fn run(args: &[String]) -> Result<(), String> {
i += 1;
break;
}
"--connect" => match args.get(i + 1).filter(|a| a.contains(':') && !a.contains('=')) {
Some(a) => {
connect = Some(a.clone());
"--connect" => {
let (addr, took) = connect_value(args.get(i + 1).map(String::as_str));
connect = Some(addr);
if took {
i += 1;
}
None => connect = Some(DEFAULT_ADDR.to_string()),
},
a if a.starts_with("--connect=") => connect = Some(a["--connect=".len()..].to_string()),
a if a.starts_with("--connect=") => {
let (addr, _) = connect_value(Some(&a["--connect=".len()..]));
connect = Some(addr);
}
"--demo" => demo = true,
"--library" => library = Some(take_value(args, &mut i, "--library")?.to_string()),
"--import" => imports.push(take_value(args, &mut i, "--import")?.to_string()),
@@ -627,6 +630,18 @@ fn take_value<'a>(args: &'a [String], i: &mut usize, flag: &str) -> Result<&'a s
/// The port an `--connect` address names, for the recovery hint. The whole address when it has
/// no port, so a hint is never built from a guess.
/// `--connect` takes an address, or a bare port (`7980` → `127.0.0.1:7980`). A following
/// command id is left alone (#1178).
fn connect_value(next: Option<&str>) -> (String, bool) {
match next {
Some(a) if !a.starts_with('-') && a.contains(':') && !a.contains('=') => (a.to_string(), true),
Some(a) if !a.is_empty() && a.bytes().all(|c| c.is_ascii_digit()) && a.parse::<u16>().ok().is_some_and(|p| p > 0) => {
(format!("127.0.0.1:{a}"), true)
}
_ => (DEFAULT_ADDR.to_string(), false),
}
}
fn connect_port(addr: &str) -> &str {
addr.rsplit_once(':').map_or(addr, |(_, port)| port)
}
@@ -965,6 +980,20 @@ fn denoise_serve(args: &[String]) -> Result<(), String> {
serve(listener, s.model, s.tile, s.device, s.run, opts, std::sync::Arc::new(|m: &str| eprintln!("lightcraft-cli denoise-serve: {m}")))
}
#[cfg(test)]
mod connect_tests {
use super::connect_value;
#[test]
fn a_bare_port_is_loopback_and_a_command_is_not_consumed() {
assert_eq!(connect_value(Some("7980")), ("127.0.0.1:7980".into(), true));
assert_eq!(connect_value(Some("127.0.0.1:7980")), ("127.0.0.1:7980".into(), true));
assert_eq!(connect_value(Some("photo.rate")), ("127.0.0.1:7980".into(), false));
assert_eq!(connect_value(Some("0")), ("127.0.0.1:7980".into(), false));
assert_eq!(connect_value(None), ("127.0.0.1:7980".into(), false));
}
}
#[cfg(not(feature = "denoise"))]
fn denoise_serve(_: &[String]) -> Result<(), String> {
Err("denoise-serve: this build has no denoise support (build with the `denoise` feature)".into())