// bibiman - a TUI for managing BibLaTeX databases
// Copyright (C) 2024 lukeflo
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
/////
use std::path::PathBuf;
use color_eyre::eyre::Result;
use config::{ConfigError, FileFormat};
use ratatui::style::Color;
use serde::Deserialize;
use crate::cliargs::CLIArgs;
/// Main struct of the config file. Contains substructs/headings in toml
#[derive(Debug, Clone, Deserialize)]
pub struct BibiConfig {
pub general: Option,
pub colors: Option,
}
/// Substruct [general] in config.toml
#[derive(Debug, Clone, Deserialize)]
pub struct General {
pub bibfiles: Option>,
pub editor: Option,
pub pdf_opener: Option,
pub url_opener: Option,
}
/// Substruct [colors] in config.toml
#[derive(Debug, Clone, Deserialize)]
pub struct Colors {
pub main_text_color: Option,
pub highlight_text_color: Option,
pub entry_color: Option,
pub keyword_color: Option,
pub info_color: Option,
pub confirm_color: Option,
pub warn_color: Option,
pub bar_bg_color: Option,
pub popup_bg_color: Option,
pub selected_row_bg_color: Option,
}
impl Default for BibiConfig {
fn default() -> Self {
Self {
general: Some(General {
bibfiles: None,
editor: None,
pdf_opener: Some(select_opener()),
url_opener: Some(select_opener()),
}),
colors: Some(Colors {
main_text_color: Some(Color::Indexed(250)),
highlight_text_color: Some(Color::Indexed(254)),
entry_color: Some(Color::Indexed(36)),
keyword_color: Some(Color::Indexed(101)),
info_color: Some(Color::Indexed(99)),
confirm_color: Some(Color::Indexed(47)),
warn_color: Some(Color::Indexed(124)),
bar_bg_color: Some(Color::Indexed(235)),
popup_bg_color: Some(Color::Indexed(234)),
selected_row_bg_color: Some(Color::Indexed(237)),
}),
}
}
}
impl BibiConfig {
pub fn parse_config(&mut self, args: &CLIArgs) -> Result<()> {
if args.cfg_path.is_file() {
let cfg_file = Self::parse_cfg_file(args)?;
if let Some(general) = cfg_file.general {
if let Some(bibfiles) = general.bibfiles {
self.general.as_mut().unwrap().bibfiles = Some(bibfiles)
}
if let Some(editor) = general.editor {
self.general.as_mut().unwrap().editor = Some(editor)
}
if let Some(pdf_opener) = general.pdf_opener {
self.general.as_mut().unwrap().pdf_opener = Some(pdf_opener)
}
if let Some(url_opener) = general.url_opener {
self.general.as_mut().unwrap().url_opener = Some(url_opener)
}
}
if let Some(colors) = cfg_file.colors {
if let Some(main_text_color) = colors.main_text_color {
self.colors.as_mut().unwrap().main_text_color = Some(main_text_color)
}
if let Some(highlight_text_color) = colors.highlight_text_color {
self.colors.as_mut().unwrap().highlight_text_color = Some(highlight_text_color)
}
if let Some(entry_color) = colors.entry_color {
self.colors.as_mut().unwrap().entry_color = Some(entry_color)
}
if let Some(keyword_color) = colors.keyword_color {
self.colors.as_mut().unwrap().keyword_color = Some(keyword_color)
}
if let Some(info_color) = colors.info_color {
self.colors.as_mut().unwrap().info_color = Some(info_color)
}
if let Some(confirm_color) = colors.confirm_color {
self.colors.as_mut().unwrap().confirm_color = Some(confirm_color)
}
if let Some(warn_color) = colors.warn_color {
self.colors.as_mut().unwrap().warn_color = Some(warn_color)
}
if let Some(bar_bg_color) = colors.bar_bg_color {
self.colors.as_mut().unwrap().bar_bg_color = Some(bar_bg_color)
}
if let Some(popup_bg_color) = colors.popup_bg_color {
self.colors.as_mut().unwrap().popup_bg_color = Some(popup_bg_color)
}
if let Some(selected_row_bg_color) = colors.selected_row_bg_color {
self.colors.as_mut().unwrap().selected_row_bg_color =
Some(selected_row_bg_color)
}
}
}
Ok(())
}
fn parse_cfg_file(args: &CLIArgs) -> Result {
let mut cfg = config::Config::builder();
cfg = cfg.add_source(
config::File::from(args.cfg_path.clone())
.format(FileFormat::Toml)
.required(false),
);
cfg.build()?.try_deserialize()
}
/// Activates the default color scheme for light background terminals
pub fn light_colors(&mut self) {
self.colors.as_mut().unwrap().main_text_color = Some(Color::Indexed(235));
self.colors.as_mut().unwrap().highlight_text_color = Some(Color::Indexed(232));
self.colors.as_mut().unwrap().entry_color = Some(Color::Indexed(23));
self.colors.as_mut().unwrap().keyword_color = Some(Color::Indexed(58));
self.colors.as_mut().unwrap().info_color = Some(Color::Indexed(57));
self.colors.as_mut().unwrap().bar_bg_color = Some(Color::Indexed(144));
self.colors.as_mut().unwrap().popup_bg_color = Some(Color::Indexed(187));
self.colors.as_mut().unwrap().confirm_color = Some(Color::Indexed(22));
self.colors.as_mut().unwrap().selected_row_bg_color = Some(Color::Indexed(107));
}
}
fn select_opener() -> String {
match std::env::consts::OS {
"linux" => String::from("xdg-open"),
"macos" => String::from("open"),
"windows" => String::from("start"),
_ => panic!("Couldn't detect OS for setting correct opener"),
}
}