mod error; mod import; mod main; mod startup; use std::path::PathBuf; pub use super::textures::Textures; use eframe::egui::{self}; pub use error::ErrorUI; pub use import::ImporterUI; pub use main::{MainUI, UIState}; use ps_core::eyre::Report; pub use startup::StartupUI; use ps_core::{Config, DatabaseLike, FormatType}; pub enum StateUIAction { CreateDatabase { database_path: Option, emails_folder_path: PathBuf, sender_emails: Vec, format: FormatType, }, OpenDatabase { database_path: PathBuf, }, ImportDone { config: Config, total: usize, }, Close { config: Config, }, Error { report: Report, config: Config, }, Nothing, } pub enum StateUI { Startup(startup::StartupUI), Import(import::ImporterUI), Main(main::MainUI), Error(error::ErrorUI), } pub trait StateUIVariant { fn update_panel(&mut self, ctx: &egui::CtxRef, textures: &Option) -> StateUIAction; } impl StateUI { /// Create an error state pub fn error(report: Report) -> StateUI { StateUI::Error(error::ErrorUI::new(report, None)) } /// This proxies the `update` call to the individual calls in /// the `app_state` types pub fn update( &mut self, ctx: &egui::CtxRef, textures: &Option, ) { let response = match self { StateUI::Startup(panel) => panel.update_panel(ctx, textures), StateUI::Import(panel) => panel.update_panel(ctx, textures), StateUI::Main(panel) => panel.update_panel(ctx, textures), StateUI::Error(panel) => panel.update_panel(ctx, textures), }; match response { StateUIAction::CreateDatabase { database_path, emails_folder_path, sender_emails, format, } => { *self = self.create_database::( database_path, emails_folder_path, sender_emails, format, ) } StateUIAction::OpenDatabase { database_path } => { *self = self.open_database::(database_path) } StateUIAction::ImportDone { config, total } => { *self = match main::MainUI::new::(config.clone(), total) { Ok(n) => StateUI::Main(n), Err(e) => StateUI::Error(ErrorUI::new(e, Some(config))), }; } StateUIAction::Close { config } => { *self = StateUI::Startup(StartupUI::from_config(config)); } StateUIAction::Error { report, config } => { *self = StateUI::Error(error::ErrorUI::new(report, Some(config))) } StateUIAction::Nothing => (), } } } impl StateUI { #[cfg(not(target_arch = "wasm32"))] pub fn new() -> StateUI { StateUI::Startup(startup::StartupUI::default()) } #[cfg(target_arch = "wasm32")] pub fn new(config: Config, total: usize) -> StateUI { StateUI::Main(main::MainUI::new::(config, total).unwrap()) } pub fn create_database( &self, database_path: Option, emails_folder_path: PathBuf, sender_emails: Vec, format: FormatType, ) -> StateUI { let config = match Config::new(database_path, emails_folder_path, sender_emails, format) { Ok(n) => n, Err(e) => { return StateUI::Error(error::ErrorUI::new(e, None)); } }; let database = match Database::new(&config.database_path) { Ok(config) => config, Err(report) => return StateUI::Error(error::ErrorUI::new(report, None)), }; self.importer_with_config(config, database) } pub fn open_database(&mut self, database_path: PathBuf) -> StateUI { let config = match Database::config(&database_path) { Ok(config) => config, Err(report) => return StateUI::Error(error::ErrorUI::new(report, None)), }; let total = match Database::new(&database_path).and_then(|db| db.total_mails()) { Ok(config) => config, Err(report) => return StateUI::Error(error::ErrorUI::new(report, None)), }; match main::MainUI::new::(config.clone(), total) { Ok(n) => StateUI::Main(n), Err(e) => StateUI::Error(ErrorUI::new(e, Some(config))), } } fn importer_with_config( &self, config: Config, database: Database, ) -> StateUI { let importer = match import::ImporterUI::new(config.clone(), database) { Ok(n) => n, Err(e) => { return StateUI::Error(error::ErrorUI::new(e, Some(config))); } }; StateUI::Import(importer) } }