// use std::path::PathBuf; use clap::Parser; use color_eyre::eyre::eyre; use config::AppConfig; use kxio::{fs::FileSystem, net::Net, print::Printer}; mod api_result; mod check; mod config; mod execute; mod init; mod macros; mod nextcloud; mod template; mod trello; #[cfg(test)] mod tests; const NAME: &str = "trello-to-deck"; use crate::nextcloud::client::DeckClient; use crate::trello::client::TrelloClient; use execute::Execute; use kxio::kxeprintln as e; use kxio::kxprintln as p; #[derive(Parser, Debug)] #[clap(version = clap::crate_version!(), author = clap::crate_authors!(), about = clap::crate_description!())] struct Commands { #[clap(long, action = clap::ArgAction::SetTrue)] log: bool, #[clap(subcommand)] command: Command, } #[derive(Parser, Debug)] enum Command { /// Initialize the configuration #[command(about = "Initialize configuration")] Init, /// Check the configuration and connection #[command(about = "Check configuration and connection")] Check, /// Import boards from Trello to Nextcloud Deck #[command(about = "Import boards from Trello to Nextcloud Deck")] Import, /// Trello-specific commands #[command(about = "Trello-specific commands")] #[clap(subcommand)] Trello(trello::TrelloCommand), /// Nextcloud-specific commands #[command(about = "Nextcloud-specific commands")] #[clap(subcommand)] Nextcloud(nextcloud::NextcloudCommand), } #[derive(Clone)] pub struct Ctx { pub fs: FileSystem, pub net: Net, pub prt: Printer, } impl Default for Ctx { fn default() -> Self { Self { fs: kxio::fs::new(PathBuf::default()), net: kxio::net::new(), prt: kxio::print::standard(), } } } #[derive(Clone)] pub(crate) struct FullCtx { // pub fs: FileSystem, pub net: Net, pub prt: Printer, pub cfg: AppConfig, } impl FullCtx { pub(crate) fn deck_client(&self) -> DeckClient { DeckClient::new(self) } pub(crate) fn trello_client(&self) -> TrelloClient { TrelloClient::new(self) } } #[cfg_attr(test, mutants::skip)] pub async fn run(ctx: Ctx) -> color_eyre::Result<()> { color_eyre::install()?; let commands = Commands::parse(); if commands.log { tracing::subscriber::set_global_default( tracing_subscriber::FmtSubscriber::builder() .with_max_level(tracing::Level::TRACE) .finish(), )?; tracing::info!("ready"); } let cfg = AppConfig::load(&ctx); match cfg { Err(err) => { if matches!(commands.command, Command::Init) { init::run(&ctx) } else { Err(eyre!("Missing or invalid config: {err}")) } } Ok(cfg) => { commands .command .execute(FullCtx { // fs: ctx.fs, net: ctx.net, prt: ctx.prt, cfg, }) .await } } }