1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//! The [`Command`] trait, its descriptor, and the link-time registration slice.
//!
//! A `Command` is an opinionated `async fn(App) -> Result<()>` bundled
//! with a small static descriptor ([`CommandSpec`]). Commands self-
//! register via a [`linkme`] distributed slice so no manual wiring is
//! needed when authoring new commands.
//!
//! # Registration pattern
//!
//! ```ignore
//! use rtb_app::command::{BUILTIN_COMMANDS, Command, CommandSpec};
//! use rtb_app::linkme::distributed_slice;
//!
//! pub struct Deploy;
//!
//! #[async_trait::async_trait]
//! impl Command for Deploy {
//! fn spec(&self) -> &CommandSpec {
//! static SPEC: CommandSpec = CommandSpec {
//! name: "deploy",
//! about: "Deploy the thing",
//! ..CommandSpec::DEFAULT
//! };
//! &SPEC
//! }
//!
//! async fn run(&self, _app: rtb_app::app::App) -> miette::Result<()> {
//! Ok(())
//! }
//! }
//!
//! #[distributed_slice(BUILTIN_COMMANDS)]
//! fn __register_deploy() -> Box<dyn Command> { Box::new(Deploy) }
//! ```
//!
//! `rtb-cli::Application::run` iterates `BUILTIN_COMMANDS` at startup,
//! filters by the runtime `Features` set, and registers each remaining
//! command with clap.
use async_trait;
use distributed_slice;
use crateApp;
use crateFeature;
/// Static descriptor of a [`Command`].
///
/// Every field is `'static` because commands are compile-time entities —
/// runtime-generated subcommands are a separate (unimplemented) concern.
///
/// Construct with struct-update over [`CommandSpec::DEFAULT`] so new
/// optional fields do not churn every literal:
///
/// ```ignore
/// static SPEC: CommandSpec = CommandSpec {
/// name: "deploy",
/// about: "Deploy the thing",
/// ..CommandSpec::DEFAULT
/// };
/// ```
/// The contract every CLI subcommand implements.
///
/// Implementations are typically registered via the
/// [`BUILTIN_COMMANDS`] distributed slice. `rtb-cli` provides a
/// `#[rtb::command]` attribute macro that derives the boilerplate for
/// downstream tools; hand-written impls follow the example in the
/// module docs.
/// Link-time registry of [`Command`] factory functions.
///
/// The factories are thin — each produces a fresh `Box<dyn Command>`
/// when invoked by `rtb-cli::Application`. They are expected to be
/// cheap (no I/O, no allocation beyond the box). Heavy work belongs in
/// `Command::run`.
///
/// See the module docs for the registration pattern.
pub static BUILTIN_COMMANDS: ;
/// A boxed, `Send` future returned by a [`PreRunHook`].
pub type PreRunFuture =
Pin;
/// A pre-run hook, invoked with the [`App`] before command dispatch.
///
/// Runs after CLI parsing and before the matched command. Leaf crates
/// register cross-cutting pre-dispatch logic here (e.g. the self-update
/// policy check) via [`distributed_slice`], keeping `rtb-cli` decoupled
/// from them — exactly like [`BUILTIN_COMMANDS`].
///
/// **Contract:** a hook must be fast and **order-independent** — link-time
/// registration order across crates is not deterministic. A hook returning
/// `Err` aborts the run before the command executes, so advisory hooks that
/// must not block the command should swallow their own errors.
pub type PreRunHook = fn ;
/// Link-time registry of [`PreRunHook`]s run before command dispatch.
///
/// `rtb-cli::Application::run` awaits each registered hook (in unspecified
/// order) after parsing succeeds and before dispatching the matched
/// command. See [`PreRunHook`] for the contract.
pub static BUILTIN_PRERUN_HOOKS: ;