Skip to main content

schemaui_cli/tui/
mod.rs

1use std::fs;
2
3use anyhow::Result;
4use schemaui::SchemaUI;
5use schemaui::precompile::tui as pre_tui;
6
7use crate::cli::{CommonArgs, TuiSnapshotCommand};
8use crate::session::diagnostics::DiagnosticCollector;
9use crate::session::format::resolve_format_hint;
10use crate::session::schema_source::{load_optional_document, resolve_session_inputs};
11use crate::session::{SessionBundle, prepare_session};
12
13pub fn run_cli(args: &CommonArgs) -> Result<()> {
14    let session = prepare_session(args)?;
15    execute_session(session)
16}
17
18pub(crate) fn execute_session(session: SessionBundle) -> Result<()> {
19    let SessionBundle {
20        schema,
21        defaults,
22        title,
23        description,
24        output,
25    } = session;
26    let mut ui = if let Some(defaults) = defaults {
27        SchemaUI::new(defaults).with_schema(schema)
28    } else {
29        SchemaUI::from_schema(schema)
30    };
31    if let Some(title) = title {
32        ui = ui.with_title(title);
33    }
34    if let Some(description) = description {
35        ui = ui.with_description(description);
36    }
37    let value = ui.run_tui()?;
38    if let Some(options) = output {
39        options.write(&value)?;
40    }
41    Ok(())
42}
43
44pub fn run_snapshot_cli(cmd: TuiSnapshotCommand) -> Result<()> {
45    let schema_spec = cmd.common.schema.as_deref();
46    let config_spec = cmd.common.config.as_deref();
47    let mut diagnostics = DiagnosticCollector::default();
48    let schema_stdin = schema_spec == Some("-");
49    let config_stdin = config_spec == Some("-");
50    if schema_stdin && config_stdin {
51        diagnostics.push_input(
52            "schema/config",
53            "cannot read schema and config from stdin simultaneously; provide inline content, files, or a remote schema",
54        );
55    }
56    let schema_hint = resolve_format_hint(schema_spec, "schema", &mut diagnostics);
57    let config_hint = resolve_format_hint(config_spec, "config", &mut diagnostics);
58    let schema_document = load_optional_document(
59        schema_spec,
60        schema_hint.hint.format,
61        "schema",
62        schema_hint.blocked || (schema_stdin && config_stdin),
63        &mut diagnostics,
64    );
65    let config_document = load_optional_document(
66        config_spec,
67        config_hint.hint.format,
68        "config",
69        config_hint.blocked || (schema_stdin && config_stdin),
70        &mut diagnostics,
71    );
72    diagnostics.into_result()?;
73    let resolved = resolve_session_inputs(schema_document, config_document)?;
74
75    fs::create_dir_all(&cmd.out_dir)?;
76    let tui_module = cmd.out_dir.join("tui_artifacts.rs");
77    let form_module = cmd.out_dir.join("tui_form_schema.rs");
78    let layout_module = cmd.out_dir.join("tui_layout_nav.rs");
79
80    pre_tui::generate_tui_artifacts_module_from_value(
81        &resolved.schema,
82        resolved.defaults.as_ref(),
83        &tui_module,
84        &cmd.tui_fn,
85    )?;
86    pre_tui::generate_tui_form_schema_module_from_value(
87        &resolved.schema,
88        resolved.defaults.as_ref(),
89        &form_module,
90        &cmd.form_fn,
91    )?;
92    pre_tui::generate_tui_layout_nav_module_from_value(
93        &resolved.schema,
94        resolved.defaults.as_ref(),
95        &layout_module,
96        &cmd.layout_fn,
97    )?;
98
99    eprintln!("Generated TUI artifact modules:");
100    eprintln!("  TuiArtifacts module:    {:?}", tui_module);
101    eprintln!("  FormSchema module:      {:?}", form_module);
102    eprintln!("  LayoutNavModel module:  {:?}", layout_module);
103
104    Ok(())
105}