pub mod db; mod env; pub mod types; mod util; use crate::{ db::DBConfigInfoType, types::{ConfigInfoType, WithContainer, WithoutContainer}, util::{ await_termination_signal, remove_file_if_exists, stop_container, to_absolute_path, write_env_files, }, }; #[derive(Clone)] pub struct Config { pub database: DBConfigInfoType, } // relative to the pwd const API_CONFIG_PATH: &str = "../api/generated-config.yaml"; const DB_CONFIG_PATH: &str = "../../public/database/.env.generated"; pub struct DetachedHandle<'a> { stopped: bool, pub config: &'a Config, } impl<'a> DetachedHandle<'a> { pub fn new(config: &'a Config) -> Self { DetachedHandle { stopped: false, config, } } pub async fn stop(&mut self) { if self.stopped { eprintln!("Attempted to stop an already stopped DetachedHandle."); return; } self.stopped = true; stop(self.config).await; } } impl<'a> Drop for DetachedHandle<'a> { fn drop(&mut self) { if self.stopped { return; } eprintln!( "Warning: DetachedHandle was dropped without calling stop(). The container may still be running." ); } } async fn start(config: &Config) { let db_config = &config.database; // // write the config files for the api server and database client println!("Writing config files..."); write_env_files(db_config); println!("Config files written to:"); println!(" - {}", to_absolute_path(API_CONFIG_PATH).display()); println!(" - {}", to_absolute_path(DB_CONFIG_PATH).display()); } async fn stop(config: &Config) { let db_config = &config.database; // stop the container println!("Stopping container..."); stop_container(db_config, "database".to_string()).await; // remove the generated config file println!("Removing generated config file..."); remove_file_if_exists(DB_CONFIG_PATH); remove_file_if_exists(API_CONFIG_PATH); println!("Container stopped."); } pub async fn start_attached(config: &Config) { start(config).await; // wait for user input, ctrl+c, or other signals before exiting println!("Press Ctrl+C, or send SIGTERM to stop the container..."); await_termination_signal().await; stop(config).await; } #[must_use] pub async fn start_detached(config: &'_ Config) -> DetachedHandle<'_> { start(config).await; DetachedHandle::new(config) }