mod cache; mod cli; mod client; mod commands; mod config; mod dle; mod html; mod model; mod output; mod raeapi; mod suggest; mod wiktionary; use anyhow::Result; use clap::Parser; use cache::Cache; use cli::{CacheCmd, Cli, Cmd, Color, Source}; use client::Http; use commands::Ctx; use output::{ColorChoice, Style}; fn main() { if let Err(e) = run() { eprintln!("drae: {e:#}"); std::process::exit(1); } } fn run() -> Result<()> { let args = Cli::parse(); let cfg = config::load(args.config.as_deref())?; let style = Style::new( match args.color { Color::Auto => ColorChoice::Auto, Color::Always => ColorChoice::Always, Color::Never => ColorChoice::Never, }, args.width.or(cfg.width), ); let source = args.source.unwrap_or(match cfg.source.as_str() { "dle" => Source::Dle, "rae-api" => Source::RaeApi, _ => Source::Auto, }); // A cache that cannot be opened must not block lookups: carry on // without it and warn on stderr. let cache = if args.no_cache { None } else { match Cache::open(&cfg.cache) { Ok(c) => Some(c), Err(e) => { eprintln!("drae: aviso, sin caché ({e})"); None } } }; let ctx = Ctx { http: Http::new(cfg.timeout), cfg, cache, style, json: args.json, expand_abbr: args.expand_abbr, refresh: args.refresh, source, }; match (args.word, args.cmd) { (Some(word), _) => commands::define(&ctx, &word), (None, Some(cmd)) => match cmd { Cmd::Define { word } => commands::define(&ctx, &word), Cmd::Synonyms { word } => commands::synonyms(&ctx, &word), Cmd::Conjugate { verb, mood } => commands::conjugate(&ctx, &verb, mood.as_deref()), Cmd::WordOfTheDay => commands::featured(&ctx, true), Cmd::Random => commands::featured(&ctx, false), Cmd::Search { text, max } => commands::search(&ctx, &text, max), Cmd::Cache { action } => match action { CacheCmd::Info => commands::cache_info(&ctx), CacheCmd::List { max } => commands::cache_list(&ctx, max), CacheCmd::Clear => commands::cache_clear(&ctx), }, }, (None, None) => { use clap::CommandFactory; Cli::command().print_help()?; println!(); Ok(()) } } }