#![allow(clippy::derivable_impls)]
use std::{fs, path::PathBuf};
use anyhow::{Context, Result};
use clap::Parser;
use serde::Deserialize;
#[derive(Parser)]
#[command(version = env!("GEX_VERSION"), about)]
pub struct Clargs {
#[clap(default_value = ".")]
pub path: String,
#[clap(short, long, name = "PATH")]
pub config_file: Option<String>,
}
#[derive(Deserialize, Default)]
#[serde(default)]
pub struct Config {
pub options: Options,
}
#[derive(Deserialize)]
#[serde(default)]
pub struct Options {
pub auto_expand_files: bool,
pub auto_expand_hunks: bool,
pub lookahead_lines: usize,
pub truncate_lines: bool,
}
impl Default for Options {
fn default() -> Self {
Self {
auto_expand_files: false,
auto_expand_hunks: true,
lookahead_lines: 5,
truncate_lines: true,
}
}
}
impl Config {
pub fn read_from_file(path: &Option<String>) -> Result<Option<(Self, Vec<String>)>> {
let mut config_path;
if let Some(path) = path {
config_path = PathBuf::from(path);
} else if let Some(path) = dirs::config_dir() {
config_path = path;
config_path.push("gex");
config_path.push("config.toml");
} else {
return Ok(None);
}
let Ok(config) = fs::read_to_string(config_path) else {
return Ok(None);
};
let de = toml::Deserializer::new(&config);
let mut unused_keys = Vec::new();
let config = serde_ignored::deserialize(de, |path| {
unused_keys.push(path.to_string());
})
.context("failed to parse config file")?;
Ok(Some((config, unused_keys)))
}
}