#![warn(missing_docs)]
use anyhow::{anyhow, bail};
use glob::glob;
use log::{debug, error};
use serde::{de::DeserializeOwned, Serialize};
use std::{
collections::BinaryHeap,
fmt::Debug,
fs::{File, OpenOptions},
io::{Read, Write},
ops::{Deref, DerefMut},
path::PathBuf,
};
mod types;
pub use types::*;
mod history;
pub use history::*;
pub mod file;
pub use file::{FileSystemConfig, ValueType};
pub mod persist;
pub use persist::Persist;
pub mod versioned;
pub use versioned::*;
#[cfg(all(test, any(feature = "ron_config", feature = "json_config", feature = "toml_config")))]
mod test;
pub const DEFAULT_FILENAME: &str = "config";
pub trait Config: Default + Clone + PartialEq + Debug + serde::Serialize {}
impl<T: Default + Clone + PartialEq + Debug + serde::Serialize> Config for T {}
pub trait Wrapper: Deref {
fn into_inner(self) -> Self::Target;
}
pub trait SerializableConfig: Serialize {
fn save(&self) -> anyhow::Result<()>;
}
pub trait LoadableConfig {
fn load() -> anyhow::Result<Self>
where
Self: Sized;
fn load_or_default() -> Self
where
Self: Sized + Default,
{
Self::load().unwrap_or_default()
}
fn load_or_save_default() -> anyhow::Result<Self>
where
Self: Sized + Default + SerializableConfig,
{
let res = Self::load();
if res.is_err() {
Self::default().save()?;
bail!(
"Config file was not found! Saving a default config file. Please edit it and restart the application!",
);
} else {
res
}
}
}
pub trait ConfigReader<C> {
fn read_config(self) -> anyhow::Result<C>;
}
#[cfg(feature = "ron_config")]
impl<C: LoadableConfig + DeserializeOwned> ConfigReader<C> for ron::Value {
fn read_config(self) -> anyhow::Result<C> {
C::deserialize(self).map_err(|e| anyhow!(e))
}
}
#[cfg(feature = "json_config")]
impl<C: LoadableConfig + DeserializeOwned> ConfigReader<C> for serde_json::Value {
fn read_config(self) -> anyhow::Result<C> {
C::deserialize(self).map_err(|e| anyhow!(e))
}
}
#[cfg(feature = "toml_config")]
impl<C: LoadableConfig + DeserializeOwned> ConfigReader<C> for toml::Value {
fn read_config(self) -> anyhow::Result<C> {
C::deserialize(self).map_err(|e| anyhow!(e))
}
}
pub trait ConfigWriter<C> {
fn write_config(&mut self, config: &C) -> anyhow::Result<()>;
}