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