fix: last RV11 gaps - bench enum args, theme NUL paths, Zig error names
Resolves the 3 remaining gaps in docs/rewrite/notes/review-rv11-codex.md (final-Z14.md): - ghostty-bench validates every occurrence of enum options in order (Args::take_enum; empty value resets) like cli/args.zig, so `--mode=bad --mode=noop` fails as in Zig. - Theme paths with an interior NUL open the prefix like Zig's C-string path handling (verified against /usr/bin/ghostty). - Filesystem diagnostics print Zig's error names (error.FileNotFound, NotDir, AccessDenied, IsDir, NameTooLong, SymLinkLoop, ...) via a shared ghostty_os::zig_error mapping used by theme/path/config-file/ file_load/edit-config/list-themes; messages match the oracle. Test Plan: - cargo test --workspace --no-fail-fast - just check-macos (both), just check-windows, just check-wasm
This commit is contained in:
1 parent
ce9373aa7a
commit
f9b333545a
12 files changed
+215
-89
No files matched your search
@@ -122,6 +122,27 @@ impl Args {
|
||||
})
|
||||
}
|
||||
|
||||
/// Take an enum value (`parseIntoField` on an enum): every occurrence is
|
||||
/// validated against `variants` in order (a bad value is an error even if
|
||||
/// a later one is fine); an empty value resets to `default`.
|
||||
pub fn take_enum<T: Copy>(
|
||||
&mut self,
|
||||
key: &str,
|
||||
default: T,
|
||||
variants: &[(&str, T)],
|
||||
) -> Result<T, String> {
|
||||
self.apply(key, default, |v| {
|
||||
let v = v.ok_or_else(|| format!("option --{key} requires a value"))?;
|
||||
let bad = || format!("invalid value for --{key}: {}", v.to_string_lossy());
|
||||
let v = v.to_str().ok_or_else(bad)?;
|
||||
variants
|
||||
.iter()
|
||||
.find(|(n, _)| *n == v)
|
||||
.map(|(_, t)| *t)
|
||||
.ok_or_else(bad)
|
||||
})
|
||||
}
|
||||
|
||||
/// Take a file path value (any bytes are allowed).
|
||||
pub fn take_opt_path(&mut self, key: &str) -> Result<Option<PathBuf>, String> {
|
||||
self.apply(key, None, |v| {
|
||||
@@ -197,6 +218,21 @@ mod tests {
|
||||
assert!(a.take("n", 0u16).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn take_enum_validates_every_occurrence() {
|
||||
let t = |v: &[&str]| {
|
||||
Args::parse(v.iter().map(OsString::from))
|
||||
.unwrap()
|
||||
.take_enum("mode", 0u8, &[("noop", 0), ("table", 1)])
|
||||
};
|
||||
assert!(t(&["--mode=bad", "--mode=noop"]).is_err());
|
||||
assert!(t(&["--mode=noop", "--mode=bad"]).is_err());
|
||||
assert!(t(&["--mode=bad", "--mode="]).is_err());
|
||||
assert_eq!(t(&["--mode=table", "--mode="]).unwrap(), 0);
|
||||
assert_eq!(t(&["--mode=noop", "--mode=table"]).unwrap(), 1);
|
||||
assert_eq!(t(&[]).unwrap(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn duplicates_apply_in_order_and_first_error_wins() {
|
||||
let a = |v: &[&str]| Args::parse(v.iter().map(OsString::from)).unwrap();
|
||||
|
||||
Reference in new issue
Block a user