Skip to main content

haste_health/cli/
state.rs

1//! In-memory CLI state for a single invocation, plus the on-disk locations it's seeded from.
2
3use std::{
4    path::PathBuf,
5    sync::{Arc, LazyLock},
6};
7
8use haste_server::auth_n::oidc::routes::discovery::WellKnownDiscoveryDocument;
9use tokio::sync::Mutex;
10
11use crate::cli::{config::CliConfiguration, secrets::CliSecrets};
12
13/// Directory holding the CLI's config and secrets files (`~/.haste_health`).
14static CONFIG_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
15    let config_dir = std::env::home_dir()
16        .unwrap_or_else(|| std::path::PathBuf::from("."))
17        .join(".haste_health");
18
19    std::fs::create_dir_all(&config_dir).expect("Failed to create config directory");
20
21    config_dir
22});
23
24/// Non-secret profile config (server URLs, auth mode). Safe to inspect or back up.
25pub(crate) static CONFIG_LOCATION: LazyLock<PathBuf> =
26    LazyLock::new(|| CONFIG_DIR.join("config.toml"));
27
28/// Client secrets and cached OAuth tokens, kept out of `CONFIG_LOCATION` so they never
29/// show up via `config show-profile` or similar.
30pub(crate) static SECRETS_LOCATION: LazyLock<PathBuf> =
31    LazyLock::new(|| CONFIG_DIR.join(".secrets.toml"));
32
33pub(crate) struct CliState {
34    pub(crate) config: CliConfiguration,
35    pub(crate) secrets: CliSecrets,
36    pub(crate) access_token: Option<String>,
37    pub(crate) well_known_document: Option<WellKnownDiscoveryDocument>,
38}
39
40impl CliState {
41    fn new(config: CliConfiguration, secrets: CliSecrets) -> Self {
42        CliState {
43            config,
44            secrets,
45            access_token: None,
46            well_known_document: None,
47        }
48    }
49}
50
51/// Lazily loads `CONFIG_LOCATION`/`SECRETS_LOCATION` from disk on first access.
52pub(crate) static CLI_STATE: LazyLock<Arc<Mutex<CliState>>> = LazyLock::new(|| {
53    let config = crate::cli::config::load_config(&CONFIG_LOCATION);
54    let secrets = crate::cli::secrets::load_secrets(&SECRETS_LOCATION);
55
56    Arc::new(Mutex::new(CliState::new(config, secrets)))
57});