use std::{ io::{BufReader, Read, Write}, path::PathBuf, process::Command, }; use clap::{Parser, Subcommand}; use icu_locid::{langid, LanguageIdentifier}; use l10n_db::{self, js, read_file, xliff, Bundle, Editor, ReadError}; use serde::Deserialize; #[derive(Parser)] #[command(version, about, long_about = None)] struct Cli { #[command(subcommand)] command: Option<Commands>, } #[derive(Subcommand)] enum Commands { /// Edit, potentially creating, a key EditKey { #[arg(short, long)] name: String, #[arg(short, long)] locale: String, }, /// List al keys in the database ListKeys, // Search the database // Search { }, /// Export the database Export { #[arg(short, long)] format: String, #[arg(short, long)] locale: Option<String>, }, } #[derive(Debug, Deserialize)] struct Config { db_path: PathBuf, base_locale: LanguageIdentifier, locales: Vec<LanguageIdentifier>, } fn edit_key(bundle: &mut Bundle, key: String, locale: LanguageIdentifier, editor: &str) { let message = bundle.message(key); Editor::edit(message, locale, editor); bundle.save(); } fn main() { let editor = std::env::var("EDITOR").expect("Set EDITOR to the path to your favorite editor"); let config: Config = read_file(&PathBuf::from("./config.toml")) .and_then(|bytes| String::from_utf8(bytes).map_err(|_| ReadError::InvalidFormat)) .and_then(|content| toml::from_str(&content).map_err(|_| ReadError::InvalidFormat)) .unwrap(); let cli = Cli::parse(); let mut bundle = Bundle::load_from_disk(PathBuf::from(&config.db_path)); match &cli.command { Some(Commands::EditKey { name, locale }) => { let identifier = locale.parse::<LanguageIdentifier>().unwrap(); edit_key(&mut bundle, name.to_owned(), identifier, &editor) } Some(Commands::ListKeys) => { for (key, _) in bundle.message_iter() { println!("{}", key); } } Some(Commands::Export { format, locale }) => { let locale = locale.as_ref().map(|l| l.clone().parse::<LanguageIdentifier>().unwrap()).unwrap_or(langid!("en")); match format.as_ref() { "js" => js::export_file(&bundle, locale, &PathBuf::from("output.json")).unwrap(), "xliff" => xliff::export_file(&bundle, locale, &PathBuf::from("output.xliff")).unwrap(), _ => todo!(), } }, None => {} } }