use crate::config::AppConfig; use crate::container::Container; use anyhow::Result; use applib::cli::{CliArgs, Command, commands}; use clap::Parser; use tokio::signal; use tracing::{debug, info, warn}; pub struct Application { config: AppConfig, container: Container, command: Command, } impl Application { pub async fn build() -> Result { let args = CliArgs::parse(); let config = AppConfig::build(&args.global, &args.command)?; tracing_subscriber::fmt() .compact() .with_env_filter(&config.log_level) .with_target(false) .init(); debug!("Bootstrapping application..."); let container = Container::new(&config).await?; Ok(Self { config, container, command: args.command, }) } pub async fn run(self) -> Result<()> { match self.command { Command::Server(_) => { commands::server::run(self.config.server, Self::wait_for_shutdown_signal()).await; } Command::Decode(_) => { commands::decode::run(self.config.decoder).await; } Command::ImportDict(_) => { commands::import_dict::run( self.config.import_dict, self.container.dict_repository.clone(), ) .await?; } } Ok(()) } async fn wait_for_shutdown_signal() { match signal::ctrl_c().await { Ok(()) => { info!("Received shutdown signal (SIGINT/SIGTERM)"); } Err(err) => { warn!("Failed to listen for shutdown signal: {}", err); } } } }