ced/src/app/config.rs

146 lines
3.9 KiB
Rust
Raw Normal View History

2025-07-05 14:42:45 -04:00
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use super::theme::Theme;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
#[serde(default = "default_auto_hide_toolbar")]
2025-07-05 14:42:45 -04:00
pub auto_hide_toolbar: bool,
2025-07-15 20:08:38 -04:00
#[serde(default = "default_hide_tab_bar")]
pub hide_tab_bar: bool,
#[serde(default = "default_show_line_numbers")]
2025-07-05 14:42:45 -04:00
pub show_line_numbers: bool,
#[serde(default = "default_word_wrap")]
2025-07-05 14:42:45 -04:00
pub word_wrap: bool,
#[serde(default = "Theme::default")]
2025-07-05 14:42:45 -04:00
pub theme: Theme,
#[serde(default = "default_line_side")]
2025-07-05 14:42:45 -04:00
pub line_side: bool,
#[serde(default = "default_font_family")]
2025-07-05 14:42:45 -04:00
pub font_family: String,
#[serde(default = "default_font_size")]
2025-07-05 14:42:45 -04:00
pub font_size: f32,
// pub vim_mode: bool,
}
2025-07-15 20:08:38 -04:00
fn default_auto_hide_toolbar() -> bool {
false
}
fn default_hide_tab_bar() -> bool {
true
}
fn default_show_line_numbers() -> bool {
false
}
fn default_word_wrap() -> bool {
true
}
fn default_line_side() -> bool {
false
}
fn default_font_family() -> String {
"Proportional".to_string()
}
fn default_font_size() -> f32 {
14.0
}
2025-07-05 14:42:45 -04:00
impl Default for Config {
fn default() -> Self {
Self {
auto_hide_toolbar: false,
2025-07-15 20:08:38 -04:00
hide_tab_bar: true,
2025-07-05 14:42:45 -04:00
show_line_numbers: false,
word_wrap: true,
theme: Theme::default(),
line_side: false,
font_family: "Proportional".to_string(),
font_size: 14.0,
// vim_mode: false,
}
}
}
impl Config {
pub fn config_path() -> Option<PathBuf> {
let config_dir = if let Some(config_dir) = dirs::config_dir() {
config_dir.join(format!("{}", env!("CARGO_PKG_NAME")))
2025-07-05 14:42:45 -04:00
} else if let Some(home_dir) = dirs::home_dir() {
2025-07-15 20:08:38 -04:00
home_dir
.join(".config")
.join(format!("{}", env!("CARGO_PKG_NAME")))
2025-07-05 14:42:45 -04:00
} else {
return None;
};
Some(config_dir.join("config.toml"))
}
pub fn load() -> Self {
let config_path = match Self::config_path() {
Some(path) => path,
None => return Self::default(),
};
if !config_path.exists() {
let default_config = Self::default();
if let Err(e) = default_config.save() {
2025-07-15 00:42:01 -04:00
eprintln!("Failed to create default config file: {e}");
2025-07-05 14:42:45 -04:00
}
return default_config;
}
match std::fs::read_to_string(&config_path) {
Ok(content) => {
let mut config = match toml::from_str::<Config>(&content) {
Ok(config) => config,
Err(e) => {
eprintln!(
"Failed to parse config file {}: {}",
config_path.display(),
e
);
return Self::default();
}
};
let default_config = Self::default();
config.merge_with_default(default_config);
config
2025-07-15 20:08:38 -04:00
}
2025-07-05 14:42:45 -04:00
Err(e) => {
eprintln!(
"Failed to read config file {}: {}",
config_path.display(),
e
);
Self::default()
}
}
}
fn merge_with_default(&mut self, default: Config) {
if self.font_family.is_empty() {
self.font_family = default.font_family;
}
2025-07-15 20:08:38 -04:00
if self.font_size <= 0.0 {
self.font_size = default.font_size;
}
}
2025-07-05 14:42:45 -04:00
pub fn save(&self) -> Result<(), Box<dyn std::error::Error>> {
let config_path = Self::config_path().ok_or("Cannot determine config directory")?;
if let Some(parent) = config_path.parent() {
std::fs::create_dir_all(parent)?;
}
let content = toml::to_string_pretty(self)?;
std::fs::write(&config_path, content)?;
Ok(())
}
}