use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::error::WikiError;
use crate::theme::Theme;
const APP_NAME: &str = "wiky";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub language: String,
pub theme: String,
pub width: u16,
pub pager: bool,
pub results_count: u8,
pub open_urls: bool,
pub show_image_alt: bool,
pub max_article_bytes: usize,
pub custom_theme: Theme,
}
impl Default for Config {
fn default() -> Self {
Self {
language: "en".into(),
theme: "dark".into(),
width: 0,
pager: false,
results_count: 10,
open_urls: false,
show_image_alt: false,
max_article_bytes: 0,
custom_theme: Theme::dark(),
}
}
}
impl Config {
pub fn load() -> Result<Self, WikiError> {
let cfg: Self = confy::load(APP_NAME, None)?;
Ok(cfg)
}
pub fn save(&self) -> Result<(), WikiError> {
confy::store(APP_NAME, None, self)?;
Ok(())
}
pub fn path() -> Option<PathBuf> {
confy::get_configuration_file_path(APP_NAME, None).ok()
}
pub fn active_theme(&self) -> Theme {
if self.theme.eq_ignore_ascii_case("custom") {
return self.custom_theme.clone();
}
Theme::by_name(&self.theme).unwrap_or_else(Theme::dark)
}
pub fn api_url(&self) -> String {
format!(
"https://{}.wikipedia.org/w/api.php",
self.language.to_lowercase()
)
}
pub fn effective_width(&self) -> u16 {
if self.width > 0 {
self.width
} else {
terminal_width()
}
}
}
pub fn terminal_width() -> u16 {
if let Ok(cols) = std::env::var("COLUMNS") {
if let Ok(n) = cols.parse::<u16>() {
if n > 0 {
return n;
}
}
}
#[cfg(not(test))]
if let Some((terminal_size::Width(w), _)) = terminal_size::terminal_size() {
if w > 0 {
return w;
}
}
80
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_config_is_valid() {
let c = Config::default();
assert_eq!(c.language, "en");
assert_eq!(c.results_count, 10);
}
#[test]
fn api_url_uses_language() {
let mut c = Config::default();
c.language = "id".into();
assert_eq!(c.api_url(), "https://id.wikipedia.org/w/api.php");
}
#[test]
fn active_theme_builtin() {
let mut c = Config::default();
c.theme = "nord".into();
let t = c.active_theme();
assert_eq!(t.title, "#88C0D0");
}
#[test]
fn active_theme_custom() {
let mut c = Config::default();
c.theme = "custom".into();
c.custom_theme.title = "#AABBCC".into();
assert_eq!(c.active_theme().title, "#AABBCC");
}
}