1use std::{
2 path::PathBuf,
3 sync::{Arc, LazyLock},
4};
5
6use clap::{Parser, Subcommand};
7use haste_fhir_operation_error::OperationOutcomeError;
8use haste_server::auth_n::oidc::routes::discovery::WellKnownDiscoveryDocument;
9use tokio::sync::Mutex;
10
11use crate::commands::config::{CLIConfiguration, load_config};
12
13mod commands;
14
15#[derive(Parser)]
16#[command(version, about, long_about = None)] struct Cli {
18 #[command(subcommand)]
19 command: CLICommand,
20}
21
22#[derive(Subcommand)]
23enum CLICommand {
24 FHIRPath {
26 fhirpath: String,
28 },
29 Generate {
30 #[command(subcommand)]
32 command: commands::codegen::CodeGen,
33 },
34 Server {
35 #[command(subcommand)]
36 command: commands::server::ServerCommands,
37 },
38 Api {
39 #[command(subcommand)]
40 command: commands::api::ApiCommands,
41 },
42 Config {
43 #[command(subcommand)]
44 command: commands::config::ConfigCommands,
45 },
46 Worker {},
47}
48
49static CONFIG_LOCATION: LazyLock<PathBuf> = LazyLock::new(|| {
50 let config_dir = std::env::home_dir()
51 .unwrap_or_else(|| std::path::PathBuf::from("."))
52 .join(".haste_health");
53
54 std::fs::create_dir_all(&config_dir).expect("Failed to create config directory");
55
56 config_dir.join("config.toml")
57});
58
59pub struct CLIState {
60 config: CLIConfiguration,
61 access_token: Option<String>,
62 well_known_document: Option<WellKnownDiscoveryDocument>,
63}
64
65impl CLIState {
66 pub fn new(config: CLIConfiguration) -> Self {
67 CLIState {
68 config,
69 access_token: None,
70 well_known_document: None,
71 }
72 }
73}
74
75static CLI_STATE: LazyLock<Arc<Mutex<CLIState>>> = LazyLock::new(|| {
76 let config = load_config(&CONFIG_LOCATION);
77
78 Arc::new(Mutex::new(CLIState::new(config)))
79});
80
81#[tokio::main]
82async fn main() -> Result<(), OperationOutcomeError> {
83 let cli = Cli::parse();
84 let config = CLI_STATE.clone();
85
86 match &cli.command {
87 CLICommand::FHIRPath { fhirpath } => commands::fhirpath::fhirpath(fhirpath),
88 CLICommand::Generate { command } => commands::codegen::codegen(command).await,
89 CLICommand::Server { command } => commands::server::server(command).await,
90 CLICommand::Worker {} => commands::worker::worker().await,
91 CLICommand::Config { command } => commands::config::config(&config, command).await,
92 CLICommand::Api { command } => commands::api::api_commands(config, command).await,
93 }
94}