Skip to main content

nomad_cli/
format.rs

1use crate::cli::FormatArgs;
2
3const FORMATS: &[(u8, &str, &str, &str)] = &[
4    (0,  "RAW",       "874 B",  "Machine IPC — binary bincode EcsFrame"),
5    (1,  "JSON",      "2223 B", "Full verbose debug with bounds and styles"),
6    (2,  "MARKDOWN",  "159 B",  "Human-readable Markdown"),
7    (3,  "AGENT",     "683 B",  "LLM analysis with roles and intents"),
8    (4,  "SUMMARY",   "107 B",  "LLM token-efficient — interactive only"),
9    (5,  "MINIMAL",   "326 B",  "Shortest JSON — single-char keys"),
10    (6,  "SECTION",   "348 B",  "Interactive by HTML5 landmarks"),
11    (7,  "A11Y",      "299 B",  "ARIA accessibility tree"),
12    (8,  "TREE",      "367 B",  "Nested hierarchical DOM tree"),
13    (9,  "READER",    "125 B",  "Clean article body (Reader Mode)"),
14    (10, "FORM",      "12 B",   "Structured form fields"),
15];
16
17pub fn run(args: FormatArgs) -> Result<(), Box<dyn std::error::Error>> {
18    match args.format {
19        Some(f) => show_detail(&f),
20        None => show_all(),
21    }
22}
23
24fn show_all() -> Result<(), Box<dyn std::error::Error>> {
25    println!("Available output formats:");
26    println!();
27    for (id, name, size, desc) in FORMATS {
28        let default = if *id == 4 { " ◄ default" } else { "" };
29        println!("  {id:2}  {name:<10} {size:<7} {desc}{default}");
30    }
31    println!();
32    println!("Use with: nom browse <url> --format <name|number>");
33    Ok(())
34}
35
36fn show_detail(name: &str) -> Result<(), Box<dyn std::error::Error>> {
37    if name == "list" || name == "all" {
38        return show_all();
39    }
40    let id = if let Ok(n) = name.parse::<u8>() {
41        n
42    } else {
43        match name.to_lowercase().as_str() {
44            "raw" => 0, "json" => 1, "markdown" | "md" => 2,
45            "agent" => 3, "summary" => 4, "minimal" => 5,
46            "section" => 6, "a11y" => 7, "tree" => 8,
47            "reader" => 9, "form" => 10,
48            _ => {
49                println!("Unknown format: {name}");
50                println!("Valid: raw, json, markdown, agent, summary, minimal, section, a11y, tree, reader, form");
51                return Ok(());
52            }
53        }
54    };
55
56    if let Some((_, name, size, desc)) = FORMATS.iter().find(|(i, _, _, _)| *i == id) {
57        println!("Format {id}: {name}");
58        println!("  Default size: {size}");
59        println!("  Description: {desc}");
60        println!();
61        print_example(id);
62    }
63    Ok(())
64}
65
66fn print_example(fmt: u8) {
67    match fmt {
68        0 => println!("  Binary — not human-readable. Pipe to a file."),
69        1 => println!("  Example: {{\"tab_id\":1,\"viewport\":{{\"width\":800,\"height\":600}},\"entities\":[...]}}"),
70        2 => println!("  Example: # Title\\n\\nParagraph text..."),
71        3 => println!("  Example: {{\"tab_id\":1,\"viewport\":[800,600],\"entities\":[{{\"id\":1,\"tag\":\"a\",\"text\":\"...\"}}]}}"),
72        4 => println!("  Example: {{\"title\":\"...\",\"url\":\"...\",\"count\":5,\"interactive\":[{{\"id\":4,\"t\":\"a\",\"x\":\"...\"}}]}}"),
73        5 => println!("  Example: [{{\"i\":0,\"t\":\"h1\",\"x\":\"...\"}}]"),
74        6 => println!("  Example: {{\"sections\":{{\"nav\":[...],\"main\":[...]}}}}"),
75        7 => println!("  Example: [{{\"role\":\"heading\",\"name\":\"...\"}}]"),
76        8 => println!("  Example: {{\"t\":\"root\",\"c\":[{{\"i\":0,\"t\":\"h1\",\"x\":\"...\"}}]}}"),
77        9 => println!("  Example: # Title\\n\\nClean article body..."),
78        10 => println!("  Example: {{\"forms\":[{{\"fields\":[{{\"name\":\"email\",\"type\":\"text\"}}]}}]}}"),
79        _ => {}
80    }
81}