rtb_cli/init.rs
1//! Initialisers — the `init` subcommand's plug-in point.
2
3use async_trait::async_trait;
4use linkme::distributed_slice;
5use rtb_app::app::App;
6
7/// A pluggable bootstrap step run by the `init` subcommand.
8///
9/// Initialisers typically prompt for configuration values, write a
10/// user config file, set up OS keychain entries, generate SSH keys,
11/// etc. The `init` command iterates every registered initialiser in
12/// registration order, skipping any that report `is_configured ==
13/// true` unless the user passes `--force`.
14#[async_trait]
15pub trait Initialiser: Send + Sync + 'static {
16 /// Short identifier shown in `init` output.
17 fn name(&self) -> &'static str;
18
19 /// Returns `true` if this initialiser's prerequisites are already
20 /// met — e.g. the relevant config key is present.
21 async fn is_configured(&self, app: &App) -> bool;
22
23 /// Perform the bootstrap. Typically interactive.
24 async fn configure(&self, app: &App) -> miette::Result<()>;
25}
26
27/// Link-time registry of initialiser factories.
28///
29/// ```ignore
30/// use rtb_cli::init::{Initialiser, INITIALISERS};
31/// use rtb_app::linkme::distributed_slice;
32///
33/// #[distributed_slice(INITIALISERS)]
34/// fn register() -> Box<dyn Initialiser> { Box::new(MyInitialiser) }
35/// ```
36#[distributed_slice]
37pub static INITIALISERS: [fn() -> Box<dyn Initialiser>];