chrysopoeia/src/settings.rs

93 lines
2.2 KiB
Rust

use std::{
fs::read_to_string,
io,
path::{Path, PathBuf},
};
use lazy_static::lazy_static;
use serde::Deserialize;
use crate::{
console::warning,
install::languages::{LanguageDb, LanguageDefs},
};
lazy_static! {
static ref XDG: xdg::BaseDirectories =
xdg::BaseDirectories::with_prefix("chrysopoeia").unwrap();
}
#[derive(Debug, Default, Deserialize)]
pub struct Settings {
#[serde(default = "default_data_dir")]
pub data_dir: PathBuf,
#[serde(default)]
pub install: InstallSettings,
#[serde(rename = "languages")]
pub user_language_defs: Option<LanguageDefs>,
}
#[derive(Debug, Default, Deserialize)]
pub struct InstallSettings {
#[serde(alias = "cc")]
pub compiler: Option<String>,
}
fn default_data_dir() -> PathBuf {
if cfg!(debug_assertions) {
"share".into()
} else {
XDG.get_data_home()
}
}
pub fn default_config() -> PathBuf {
if cfg!(debug_assertions) {
"chrysopoeia.toml".into()
} else {
XDG.get_config_file("config.toml")
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("unable to read config file: {0}")]
Io(#[from] io::Error),
#[error("{file:?}: {e}")]
Toml { file: PathBuf, e: toml::de::Error },
}
pub fn get_settings(path: &Path) -> Result<Settings, Error> {
toml::from_str(&read_to_string(path)?).map_err(|e| Error::Toml {
file: path.to_owned(),
e,
})
}
impl Settings {
pub fn parser_dir(&self) -> PathBuf {
self.data_dir.join("parsers")
}
/// note: this method moves out of self.user_language_defs
pub fn language_defs(&mut self) -> Result<LanguageDb, Error> {
let mut sources: Vec<LanguageDefs> = self.user_language_defs.take().into_iter().collect();
let default_path = self.data_dir.join("languages.toml");
match read_to_string(&default_path) {
Ok(default_defs) => {
sources.push(toml::from_str(&default_defs).map_err(|e| Error::Toml {
file: default_path,
e,
})?)
}
Err(e) => warning!("couldn't read language install info from {default_path:?}: {e}"),
}
Ok(LanguageDb::new(sources))
}
}