Skip to main content

dsp_cli/
lib.rs

1//! `dsp-cli` — AI-agent-friendly CLI for the DaSCH Service Platform.
2//!
3//! The orientation entry point is `idea.md` in the repository root; the
4//! ubiquitous-language reference is `CONTEXT.md`. The internal architecture
5//! is described in ADR-0008 (`docs/adr/0008-internal-architecture.md`).
6//!
7//! This crate exposes a library surface so tests can reach the action layer
8//! without going through the binary; the binary itself is `src/main.rs`.
9
10pub mod actions;
11pub mod cli;
12pub mod client;
13pub mod config;
14pub mod diagnostic;
15pub mod model;
16pub mod render;
17pub(crate) mod util;
18
19use crate::cli::{
20    AuthCmd, Cli, DataModelCmd, ProjectCmd, ResourceCmd, ResourceTypeCmd, TopLevel, VreCmd,
21};
22use crate::client::http::HttpDspClient;
23use crate::config::Config;
24use crate::diagnostic::Diagnostic;
25
26/// Top-level entry point used by `main.rs` and by integration tests.
27///
28/// Routes CLI commands to the appropriate action function. The match is
29/// exhaustive — adding a new variant forces an explicit dispatch update.
30///
31/// For vre leaf commands and auth commands, the renderer is constructed from
32/// the `--format` / `-j` / `-l` flags parsed into `FormatArgs` and resolved
33/// via `FormatArgs::resolve().into_renderer()`. The auth commands additionally
34/// build a `Config` from `--server`/`DSP_SERVER` and, for login, an
35/// `HttpDspClient`.
36pub fn run(cli: Cli) -> Result<(), Diagnostic> {
37    match cli.command {
38        TopLevel::Auth { cmd } => match cmd {
39            AuthCmd::Login(args) => {
40                let cfg = Config::resolve(args.server.as_deref())?;
41                let client = HttpDspClient::new()?;
42                let fmt = args.format.resolve();
43                let opts = args.format.table_options(fmt)?;
44                let mut renderer = fmt.into_renderer_with_options(opts);
45                actions::auth::login::run(&args, &cfg, &client, &mut *renderer)
46            }
47            AuthCmd::Status(args) => {
48                let cfg = Config::resolve(args.server.as_deref())?;
49                let fmt = args.format.resolve();
50                let opts = args.format.table_options(fmt)?;
51                let mut renderer = fmt.into_renderer_with_options(opts);
52                actions::auth::status::run(&args, &cfg, &mut *renderer)
53            }
54            AuthCmd::Logout(args) => {
55                let cfg = Config::resolve(args.server.as_deref())?;
56                let fmt = args.format.resolve();
57                let opts = args.format.table_options(fmt)?;
58                let mut renderer = fmt.into_renderer_with_options(opts);
59                actions::auth::logout::run(&args, &cfg, &mut *renderer)
60            }
61            AuthCmd::SetToken(args) => {
62                let cfg = Config::resolve(args.server.as_deref())?;
63                let client = HttpDspClient::new()?;
64                let fmt = args.format.resolve();
65                let opts = args.format.table_options(fmt)?;
66                let mut renderer = fmt.into_renderer_with_options(opts);
67                actions::auth::set_token::run(&cfg, &client, &mut *renderer)
68            }
69            AuthCmd::Token(args) => {
70                let cfg = Config::resolve(args.server.as_deref())?;
71                actions::auth::token::run(&cfg)
72            }
73        },
74
75        TopLevel::Vre { cmd } => match cmd {
76            VreCmd::Project { cmd } => match cmd {
77                ProjectCmd::List(args) => {
78                    let cfg = Config::resolve(args.server.as_deref())?;
79                    let client = HttpDspClient::new()?;
80                    let fmt = args.format.resolve();
81                    let opts = args.format.table_options(fmt)?;
82                    let mut renderer = fmt.into_renderer_with_options(opts);
83                    actions::vre::project::list(&args, &cfg, &client, &mut *renderer)
84                }
85                ProjectCmd::Describe(args) => {
86                    let cfg = Config::resolve(args.server.as_deref())?;
87                    let client = HttpDspClient::new()?;
88                    let fmt = args.format.resolve();
89                    let opts = args.format.table_options(fmt)?;
90                    let mut renderer = fmt.into_renderer_with_options(opts);
91                    actions::vre::project::describe(&args, &cfg, &client, &mut *renderer)
92                }
93                ProjectCmd::Dump(args) => {
94                    let cfg = Config::resolve(args.server.as_deref())?;
95                    let client = HttpDspClient::new()?;
96                    let fmt = args.format.resolve();
97                    let opts = args.format.table_options(fmt)?;
98                    let mut renderer = fmt.into_renderer_with_options(opts);
99                    let mut reporter = fmt.into_progress_reporter();
100                    actions::vre::project::dump(
101                        &args,
102                        &cfg,
103                        &client,
104                        &mut *renderer,
105                        &mut *reporter,
106                    )
107                }
108            },
109            VreCmd::DataModel { cmd } => match cmd {
110                DataModelCmd::List(args) => {
111                    let cfg = Config::resolve(args.server.as_deref())?;
112                    let client = HttpDspClient::new()?;
113                    let fmt = args.format.resolve();
114                    let opts = args.format.table_options(fmt)?;
115                    let mut renderer = fmt.into_renderer_with_options(opts);
116                    actions::vre::data_model::list(&args, &cfg, &client, &mut *renderer)
117                }
118                DataModelCmd::Describe(args) => {
119                    let cfg = Config::resolve(args.server.as_deref())?;
120                    let client = HttpDspClient::new()?;
121                    let fmt = args.format.resolve();
122                    let opts = args.format.table_options(fmt)?;
123                    let mut renderer = fmt.into_renderer_with_options(opts);
124                    actions::vre::data_model::describe(&args, &cfg, &client, &mut *renderer)
125                }
126                DataModelCmd::Structure(args) => {
127                    let cfg = Config::resolve(args.server.as_deref())?;
128                    let client = HttpDspClient::new()?;
129                    let fmt = args.format.resolve();
130                    let opts = args.format.table_options(fmt)?;
131                    let mut renderer = fmt.into_renderer_with_options(opts);
132                    actions::vre::data_model::structure(&args, &cfg, &client, &mut *renderer)
133                }
134            },
135            VreCmd::ResourceType { cmd } => match cmd {
136                ResourceTypeCmd::List(args) => {
137                    let cfg = Config::resolve(args.server.as_deref())?;
138                    let client = HttpDspClient::new()?;
139                    let fmt = args.format.resolve();
140                    let opts = args.format.table_options(fmt)?;
141                    let mut renderer = fmt.into_renderer_with_options(opts);
142                    actions::vre::resource_type::list(&args, &cfg, &client, &mut *renderer)
143                }
144                ResourceTypeCmd::Describe(args) => {
145                    let cfg = Config::resolve(args.server.as_deref())?;
146                    let client = HttpDspClient::new()?;
147                    let fmt = args.format.resolve();
148                    let opts = args.format.table_options(fmt)?;
149                    let mut renderer = fmt.into_renderer_with_options(opts);
150                    actions::vre::resource_type::describe(&args, &cfg, &client, &mut *renderer)
151                }
152            },
153            VreCmd::Resource { cmd } => match cmd {
154                ResourceCmd::List(args) => {
155                    let cfg = Config::resolve(args.server.as_deref())?;
156                    let client = HttpDspClient::new()?;
157                    let fmt = args.format.resolve();
158                    let opts = args.format.table_options(fmt)?;
159                    let mut renderer = fmt.into_renderer_with_options(opts);
160                    actions::vre::resource::list(&args, &cfg, &client, &mut *renderer)
161                }
162                ResourceCmd::Describe(args) => {
163                    let cfg = Config::resolve(args.server.as_deref())?;
164                    let client = HttpDspClient::new()?;
165                    let fmt = args.format.resolve();
166                    let opts = args.format.table_options(fmt)?;
167                    let mut renderer = fmt.into_renderer_with_options(opts);
168                    actions::vre::resource::describe(&args, &cfg, &client, &mut *renderer)
169                }
170            },
171        },
172
173        TopLevel::Docs(args) => actions::docs::run(&args),
174    }
175}