diff options
author | Ellie Huxtable <e@elm.sh> | 2021-03-10 21:24:08 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-10 21:24:08 +0000 |
commit | 61607e023fbb916f376a7070f8b1ffd6ffe16849 (patch) | |
tree | eadc28b084e0d07f6e3fd0fcaa4c74f2f840c04c /src | |
parent | b42d93dcc88c8faf94dee13c93288d0bab0a7b13 (diff) |
Add config file support (#15)
Diffstat (limited to 'src')
-rw-r--r-- | src/command/mod.rs | 5 | ||||
-rw-r--r-- | src/command/stats.rs | 8 | ||||
-rw-r--r-- | src/main.rs | 19 | ||||
-rw-r--r-- | src/settings.rs | 64 |
4 files changed, 83 insertions, 13 deletions
diff --git a/src/command/mod.rs b/src/command/mod.rs index 0952540b..c74b138f 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -3,6 +3,7 @@ use structopt::StructOpt; use uuid::Uuid; use crate::local::database::Database; +use crate::settings::Settings; mod history; mod import; @@ -39,12 +40,12 @@ pub fn uuid_v4() -> String { } impl AtuinCmd { - pub fn run(self, db: &mut impl Database) -> Result<()> { + pub fn run(self, db: &mut impl Database, settings: &Settings) -> Result<()> { match self { Self::History(history) => history.run(db), Self::Import(import) => import.run(db), Self::Server(server) => server.run(), - Self::Stats(stats) => stats.run(db), + Self::Stats(stats) => stats.run(db, settings), Self::Init => init::init(), Self::Uuid => { diff --git a/src/command/stats.rs b/src/command/stats.rs index 19079b8d..694484bc 100644 --- a/src/command/stats.rs +++ b/src/command/stats.rs @@ -10,6 +10,7 @@ use structopt::StructOpt; use crate::local::database::Database; use crate::local::history::History; +use crate::settings::Settings; #[derive(StructOpt)] pub enum Cmd { @@ -70,7 +71,7 @@ fn compute_stats(history: &[History]) -> Result<()> { } impl Cmd { - pub fn run(&self, db: &mut impl Database) -> Result<()> { + pub fn run(&self, db: &mut impl Database, settings: &Settings) -> Result<()> { match self { Self::Day { words } => { let words = if words.is_empty() { @@ -79,7 +80,10 @@ impl Cmd { words.join(" ") }; - let start = parse_date_string(&words, Local::now(), Dialect::Us)?; + let start = match settings.local.dialect.to_lowercase().as_str() { + "uk" => parse_date_string(&words, Local::now(), Dialect::Uk)?, + _ => parse_date_string(&words, Local::now(), Dialect::Us)?, + }; let end = start + Duration::days(1); let history = db.range(start.into(), end.into())?; diff --git a/src/main.rs b/src/main.rs index 380df592..78e10731 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,10 @@ -#![feature(str_split_once)] #![feature(proc_macro_hygiene)] #![feature(decl_macro)] #![warn(clippy::pedantic, clippy::nursery)] +#![allow(clippy::use_self)] // not 100% reliable use std::path::PathBuf; -use directories::ProjectDirs; use eyre::{eyre, Result}; use structopt::StructOpt; @@ -15,12 +14,17 @@ extern crate log; #[macro_use] extern crate rocket; +#[macro_use] +extern crate serde_derive; + use command::AtuinCmd; use local::database::Sqlite; +use settings::Settings; mod command; mod local; mod remote; +mod settings; #[derive(StructOpt)] #[structopt( @@ -38,6 +42,8 @@ struct Atuin { impl Atuin { fn run(self) -> Result<()> { + let settings = Settings::new()?; + let db_path = if let Some(db_path) = self.db { let path = db_path .to_str() @@ -45,17 +51,12 @@ impl Atuin { let path = shellexpand::full(path)?; PathBuf::from(path.as_ref()) } else { - ProjectDirs::from("com", "elliehuxtable", "atuin") - .ok_or_else(|| { - eyre!("could not determine db file location\nspecify one using the --db flag") - })? - .data_dir() - .join("history.db") + PathBuf::from(settings.local.db.path.as_str()) }; let mut db = Sqlite::new(db_path)?; - self.atuin.run(&mut db) + self.atuin.run(&mut db, &settings) } } diff --git a/src/settings.rs b/src/settings.rs new file mode 100644 index 00000000..a4c9f8da --- /dev/null +++ b/src/settings.rs @@ -0,0 +1,64 @@ +use std::path::PathBuf; + +use config::{Config, File}; +use directories::ProjectDirs; +use eyre::{eyre, Result}; +use std::fs; + +#[derive(Debug, Deserialize)] +pub struct LocalDatabase { + pub path: String, +} + +#[derive(Debug, Deserialize)] +pub struct Local { + pub server_address: String, + pub dialect: String, + pub db: LocalDatabase, +} + +#[derive(Debug, Deserialize)] +pub struct Settings { + pub local: Local, +} + +impl Settings { + pub fn new() -> Result<Self> { + let config_dir = ProjectDirs::from("com", "elliehuxtable", "atuin").unwrap(); + let config_dir = config_dir.config_dir(); + + fs::create_dir_all(config_dir)?; + + let mut config_file = PathBuf::new(); + config_file.push(config_dir); + config_file.push("config.toml"); + let config_file = config_file.as_path(); + + // create the config file if it does not exist + + let mut s = Config::new(); + + let db_path = ProjectDirs::from("com", "elliehuxtable", "atuin") + .ok_or_else(|| { + eyre!("could not determine db file location\nspecify one using the --db flag") + })? + .data_dir() + .join("history.db"); + + s.set_default("local.server_address", "https://atuin.elliehuxtable.com")?; + s.set_default("local.dialect", "us")?; + s.set_default("local.db.path", db_path.to_str())?; + + if config_file.exists() { + s.merge(File::with_name(config_file.to_str().unwrap()))?; + } + + // all paths should be expanded + let db_path = s.get_str("local.db.path")?; + let db_path = shellexpand::full(db_path.as_str())?; + s.set("local.db.path", db_path.to_string())?; + + s.try_into() + .map_err(|e| eyre!("failed to deserialize: {}", e)) + } +} |