diff --git a/Cargo.lock b/Cargo.lock index 4023d2a..844e58a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -163,6 +163,18 @@ dependencies = [ "tracing-error", ] +[[package]] +name = "confy" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37668cb35145dcfaa1931a5f37fde375eeae8068b4c0d2f289da28a270b2d2c" +dependencies = [ + "directories", + "serde", + "thiserror", + "toml", +] + [[package]] name = "csv-async" version = "1.2.4" @@ -189,12 +201,33 @@ dependencies = [ "memchr", ] +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dtmt" version = "0.1.0" dependencies = [ "clap", "color-eyre", + "confy", "csv-async", "futures", "futures-util", @@ -321,6 +354,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "gimli" version = "0.26.2" @@ -585,6 +629,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + [[package]] name = "regex" version = "1.6.0" @@ -753,6 +808,26 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.4" @@ -803,6 +878,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + [[package]] name = "tracing" version = "0.1.37" diff --git a/crates/dtmt/Cargo.toml b/crates/dtmt/Cargo.toml index 73e3d63..31250d6 100644 --- a/crates/dtmt/Cargo.toml +++ b/crates/dtmt/Cargo.toml @@ -21,6 +21,7 @@ tokio-stream = { version = "0.1.11", features = ["fs", "io-util"] } tracing = { version = "0.1.37", features = ["async-await"] } tracing-error = "0.2.0" tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } +confy = "0.5.1" [dev-dependencies] tempfile = "3.3.0" diff --git a/crates/dtmt/src/main.rs b/crates/dtmt/src/main.rs index 0272d09..2da0b16 100644 --- a/crates/dtmt/src/main.rs +++ b/crates/dtmt/src/main.rs @@ -8,6 +8,7 @@ use clap::parser::ValueSource; use clap::value_parser; use clap::{command, Arg}; use color_eyre::eyre::{Context, Result}; +use serde::{Deserialize, Serialize}; use tokio::fs::File; use tokio::io::BufReader; use tokio::sync::RwLock; @@ -25,6 +26,11 @@ mod cmd { pub mod watch; } +#[derive(Default, Deserialize, Serialize)] +struct GlobalConfig { + game_dir: Option, +} + #[tokio::main] #[tracing::instrument] async fn main() -> Result<()> { @@ -68,7 +74,7 @@ async fn main() -> Result<()> { let ctx = sdk::Context::new(); let ctx = Arc::new(RwLock::new(ctx)); - { + let dicitonary_task = { let path = matches .get_one::("dictionary") .cloned() @@ -85,21 +91,43 @@ async fn main() -> Result<()> { let f = match res { Ok(f) => f, Err(err) => { - if is_default { - return; + if !is_default { + // The dictionary is entirely optional, so only report the error + // when the user asked for a specific path. + tracing::error!("{:#}", err); } - tracing::error!("{:#}", err); - return; } }; let r = BufReader::new(f); if let Err(err) = ctx.lookup.from_csv(r).await { - tracing::error!("{:?}", err); + tracing::error!("{:#}", err); } - }); - } + }) + }; + + let global_config_task = { + let ctx = ctx.clone(); + tokio::spawn(async move { + let conf = tokio::task::spawn_blocking(|| { + confy::load::(clap::crate_name!(), None) + .wrap_err("failed to load global configuration") + }) + .await; + + match conf { + Ok(Ok(cfg)) => { + let mut ctx = ctx.write().await; + ctx.game_dir = cfg.game_dir; + } + Ok(Err(err)) => tracing::error!("{:#}", err), + Err(err) => tracing::error!("{:#}", err), + } + }) + }; + + tokio::try_join!(dicitonary_task, global_config_task)?; match matches.subcommand() { Some(("bundle", sub_matches)) => cmd::bundle::run(ctx, sub_matches).await?, diff --git a/lib/sdk/src/context.rs b/lib/sdk/src/context.rs index 77fc31d..e784a78 100644 --- a/lib/sdk/src/context.rs +++ b/lib/sdk/src/context.rs @@ -1,3 +1,4 @@ +use std::path::PathBuf; use std::sync::Arc; use tokio::sync::RwLock; @@ -11,6 +12,7 @@ pub struct Context { pub ljd: Option, pub revorb: Option, pub ww2ogg: Option, + pub game_dir: Option, } impl Context { @@ -21,6 +23,7 @@ impl Context { ljd: None, revorb: None, ww2ogg: None, + game_dir: None, } }