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
//! 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",
//! aliases: &[],
//! feature: None,
//! };
//! &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.
/// 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: ;