summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEllie Huxtable <e@elm.sh>2021-03-10 21:24:08 +0000
committerGitHub <noreply@github.com>2021-03-10 21:24:08 +0000
commit61607e023fbb916f376a7070f8b1ffd6ffe16849 (patch)
treeeadc28b084e0d07f6e3fd0fcaa4c74f2f840c04c /src
parentb42d93dcc88c8faf94dee13c93288d0bab0a7b13 (diff)
Add config file support (#15)
Diffstat (limited to 'src')
-rw-r--r--src/command/mod.rs5
-rw-r--r--src/command/stats.rs8
-rw-r--r--src/main.rs19
-rw-r--r--src/settings.rs64
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))
+ }
+}