marser_trace_viewer/
lib.rs1mod app;
9mod marker_index;
10pub mod outcome;
11pub mod replay;
12mod state;
13mod ui;
14
15use std::io;
16use std::path::PathBuf;
17
18pub use marser_trace_schema::TraceFormat;
19
20enum ParseArgs {
21 Run {
22 trace_path: PathBuf,
23 source_path: Option<PathBuf>,
24 format: Option<TraceFormat>,
25 },
26 Help,
27}
28
29pub fn run_cli() -> io::Result<()> {
31 let program = std::env::args()
32 .next()
33 .unwrap_or_else(|| "marser-trace-viewer".to_string());
34 let args = std::env::args().skip(1);
35 let parsed = match parse_args(args) {
36 Ok(v) => v,
37 Err(err) => {
38 eprintln!("{err}\n\n{}", usage(&program));
39 std::process::exit(2);
40 }
41 };
42 match parsed {
43 ParseArgs::Help => {
44 println!("{}", usage(&program));
45 std::process::exit(0);
46 }
47 ParseArgs::Run {
48 trace_path,
49 source_path,
50 format,
51 } => app::run(trace_path, source_path, format),
52 }
53}
54
55fn usage(program: &str) -> String {
56 format!(
57 "Usage: {program} --trace <path> [--source <path>] [--format json|jsonl]\n\n\
58 Keys: i(step-into) s(step-over) u(step-up)\n\
59 backspace(previous displayed event) q(quit)"
60 )
61}
62
63fn parse_args(mut args: impl Iterator<Item = String>) -> Result<ParseArgs, String> {
64 let mut trace = None;
65 let mut source = None;
66 let mut format = None;
67 while let Some(arg) = args.next() {
68 match arg.as_str() {
69 "--help" | "-h" => return Ok(ParseArgs::Help),
70 "--trace" => trace = args.next().map(PathBuf::from),
71 "--source" => source = args.next().map(PathBuf::from),
72 "--format" => {
73 format = match args.next().as_deref() {
74 Some("json") => Some(TraceFormat::Json),
75 Some("jsonl") => Some(TraceFormat::Jsonl),
76 _ => return Err("Invalid format. Use json or jsonl".to_string()),
77 }
78 }
79 _ => return Err(format!("Unknown argument: {arg}")),
80 }
81 }
82 let trace = trace.ok_or_else(|| "Missing required --trace <path>".to_string())?;
83 Ok(ParseArgs::Run {
84 trace_path: trace,
85 source_path: source,
86 format,
87 })
88}