d5baa40e
refactor: one sum owns "name one transport"
a73x 2026-08-27 08:12
Commit message
src/cli/mux_main.zig
| Old | New | ||
|---|---|---|---|
| @@ -184,24 +184,21 @@ const Opts = struct { | |||
| 184 | /// says so: they are what `positional` saw. | 184 | /// says so: they are what `positional` saw. |
| 185 | _host: ?[]const u8 = null, | 185 | _host: ?[]const u8 = null, |
| 186 | _quic: ?[]const u8 = null, | 186 | _quic: ?[]const u8 = null, |
| 187 | _conflict: bool = false, | 187 | _targets: u8 = 0, |
| 188 | 188 | ||
| 189 | pub const aliases = .{.{ "-A", "agent" }}; | 189 | pub const aliases = .{.{ "-A", "agent" }}; |
| 190 | 190 | ||
| 191 | /// A bare word is a host to hop to, `quic://...` a transport spelling. | 191 | /// A bare word is a host to hop to, `quic://...` a transport spelling. |
| 192 | /// A second of either is as ambiguous as naming two transports, so it | 192 | /// Counted, not judged: parseArgs owns the one sum that refuses two of |
| 193 | /// lands in the same refusal; `quic://` with nothing after it names no | 193 | /// anything. `quic://` with nothing after it names no host at all, and |
| 194 | /// host at all and is refused as the usage mistake it is. | 194 | /// is refused here as the usage mistake it is. |
| 195 | pub fn positional(self: *Opts, word: []const u8) bool { | 195 | pub fn positional(self: *Opts, word: []const u8) bool { |
| 196 | if (std.mem.startsWith(u8, word, "quic://")) { | 196 | if (std.mem.startsWith(u8, word, "quic://")) { |
| 197 | const host_port = word["quic://".len..]; | 197 | const host_port = word["quic://".len..]; |
| 198 | if (host_port.len == 0) return false; | 198 | if (host_port.len == 0) return false; |
| 199 | if (self._quic != null) self._conflict = true; | ||
| 200 | self._quic = host_port; | 199 | self._quic = host_port; |
| 201 | return true; | 200 | } else self._host = word; |
| 202 | } | 201 | self._targets += 1; |
| 203 | if (self._host != null) self._conflict = true; | ||
| 204 | self._host = word; | ||
| 205 | return true; | 202 | return true; |
| 206 | } | 203 | } |
| 207 | }; | 204 | }; |
| @@ -219,12 +216,10 @@ fn parseArgs(args: []const [:0]const u8, env_key: ?[]const u8) ParseError!ParseR | |||
| 219 | .unknown_arg, .missing_value, .bad_value => return error.Usage, | 216 | .unknown_arg, .missing_value, .bad_value => return error.Usage, |
| 220 | } | 217 | } |
| 221 | 218 | ||
| 222 | if (o._conflict) return error.Conflict; | 219 | // Every pairing is two transports for one session, and two bare words |
| 223 | 220 | // are a pairing too — which is why positional counts, not latches. | |
| 224 | // Every pairing of the four is two transports for one session. | ||
| 225 | const named: u8 = @as(u8, @intFromBool(o.sock != null)) + | 221 | const named: u8 = @as(u8, @intFromBool(o.sock != null)) + |
| 226 | @intFromBool(o.via != null) + @intFromBool(o._host != null) + | 222 | @intFromBool(o.via != null) + o._targets; |
| 227 | @intFromBool(o._quic != null); | ||
| 228 | if (named > 1) return error.Conflict; | 223 | if (named > 1) return error.Conflict; |
| 229 | 224 | ||
| 230 | // Rides every transport below, unlike --key: a session name is not | 225 | // Rides every transport below, unlike --key: a session name is not |