dsfb_gpu_debug_demo/cli/
generate_fixture.rs1use std::fs;
16use std::path::Path;
17use std::process::ExitCode;
18
19use dsfb_gpu_debug_core::fixture::{synthesize, DEFAULT_SEED};
20use dsfb_gpu_debug_core::serialize::write_fixture;
21
22use super::{parse_flags, require_flag, usage_error};
23
24pub fn parse_and_run(args: &[String]) -> ExitCode {
26 let flags = match parse_flags(args) {
27 Ok(f) => f,
28 Err(message) => return usage_error(&message),
29 };
30
31 let out_path = match require_flag(&flags, "out") {
32 Ok(s) => s.to_string(),
33 Err(message) => return usage_error(&message),
34 };
35
36 let seed = match flags.get("seed") {
37 None => DEFAULT_SEED,
38 Some(raw) => match parse_seed(raw) {
39 Ok(s) => s,
40 Err(message) => return usage_error(&message),
41 },
42 };
43
44 let events = synthesize(seed);
45 let bytes = write_fixture(&events);
46
47 if let Some(parent) = Path::new(&out_path).parent() {
48 if !parent.as_os_str().is_empty() {
49 if let Err(error) = fs::create_dir_all(parent) {
50 eprintln!(
51 "dsfb-gpu-debug: could not create {}: {error}",
52 parent.display()
53 );
54 return ExitCode::from(5);
55 }
56 }
57 }
58
59 if let Err(error) = fs::write(&out_path, &bytes) {
60 eprintln!("dsfb-gpu-debug: failed to write {out_path}: {error}");
61 return ExitCode::from(5);
62 }
63
64 eprintln!(
65 "dsfb-gpu-debug: wrote {n} events ({bytes} canonical bytes) to {out_path}",
66 n = events.len(),
67 bytes = bytes.len()
68 );
69 ExitCode::SUCCESS
70}
71
72fn parse_seed(raw: &str) -> Result<u64, String> {
75 if let Some(hex) = raw.strip_prefix("0x").or_else(|| raw.strip_prefix("0X")) {
76 u64::from_str_radix(hex, 16).map_err(|e| format!("invalid hex seed {raw}: {e}"))
77 } else {
78 raw.parse::<u64>()
79 .map_err(|e| format!("invalid decimal seed {raw}: {e}"))
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn parse_seed_accepts_decimal_and_hex() {
89 assert_eq!(parse_seed("0").unwrap(), 0);
90 assert_eq!(parse_seed("42").unwrap(), 42);
91 assert_eq!(parse_seed("0xff").unwrap(), 0xff);
92 assert_eq!(parse_seed("0XFF").unwrap(), 0xff);
93 assert_eq!(
94 parse_seed("0xD5FBD5FBD5FBD5FB").unwrap(),
95 0xD5FB_D5FB_D5FB_D5FB
96 );
97 }
98
99 #[test]
100 fn parse_seed_rejects_garbage() {
101 assert!(parse_seed("not a number").is_err());
102 assert!(parse_seed("0xZZZZ").is_err());
103 }
104}