generated from Astrial.org/template
73 lines
1.9 KiB
Rust
73 lines
1.9 KiB
Rust
use std::path::PathBuf;
|
|
|
|
use clap::{Parser, Subcommand};
|
|
use diaryrs::macros::UnwrapOrFatalAble;
|
|
use serde::Deserialize;
|
|
|
|
/// Overengineered and overly opinionated Rust-based diary keeper and processor.
|
|
/// Happy journaling!
|
|
#[derive(Parser)]
|
|
#[command(version, about)]
|
|
pub struct Args {
|
|
#[command(subcommand)]
|
|
pub cmd: Commands,
|
|
}
|
|
|
|
#[derive(Subcommand, Clone)]
|
|
pub enum Commands {
|
|
/// Print basic configuration information
|
|
Info,
|
|
/// Write diary entry file for today
|
|
Today,
|
|
/// Take inventory of the diary entries you have
|
|
Inventory,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct Config {
|
|
// Global options
|
|
/// The base path for diary entries
|
|
pub base_path: PathBuf,
|
|
|
|
/// Path where the config file was found. Not deserialised from the file
|
|
#[serde(skip_deserializing)]
|
|
pub config_path: PathBuf,
|
|
}
|
|
|
|
impl Config {
|
|
const CONFIG_PATHS: [&'static str; 5] = [
|
|
"diaryrs.toml",
|
|
"diary.toml",
|
|
"~/.config/diaryrs.toml",
|
|
"~/diaryrs.toml",
|
|
"~/.diaryrs.toml",
|
|
];
|
|
|
|
pub fn read() -> Result<Self, Box<dyn std::error::Error>> {
|
|
let (config_str, config_path) = try_files(
|
|
Vec::from(Self::CONFIG_PATHS)
|
|
.into_iter()
|
|
.map(|p| PathBuf::from(p))
|
|
.collect(),
|
|
)
|
|
.unwrap_or_fatal("No config file found");
|
|
let config: Config = toml::from_str(&config_str)?;
|
|
Ok(Config {
|
|
config_path,
|
|
..config
|
|
})
|
|
}
|
|
}
|
|
|
|
/// Try a list of file paths and return the contents of the first file
|
|
/// that exists. If all files have been tried none exist, None is returned
|
|
fn try_files(paths: Vec<PathBuf>) -> Option<(String, PathBuf)> {
|
|
for path in paths {
|
|
match std::fs::read_to_string(&path) {
|
|
Ok(contents) => return Some((contents, path)),
|
|
Err(_) => continue,
|
|
}
|
|
}
|
|
|
|
None
|
|
}
|