use std::path::{Path, PathBuf};
use std::{fs, io};
use crate::error::Error;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Config {
pub path: PathBuf,
#[serde(default)]
pub temporary: bool,
#[serde(default)]
pub use_compression: bool,
#[serde(default)]
pub flush_every_ms: Option<u64>,
#[serde(default)]
pub cache_capacity: Option<u64>,
#[serde(default)]
pub segment_size: Option<usize>,
}
impl Config {
pub fn new<P: AsRef<Path>>(p: P) -> Config {
Config {
path: p.as_ref().to_path_buf(),
temporary: false,
use_compression: false,
flush_every_ms: None,
cache_capacity: None,
segment_size: None,
}
}
pub fn save_to<W: io::Write>(&self, mut w: W) -> Result<(), Error> {
let s = match toml::to_string(self) {
Ok(s) => s,
Err(_) => return Err(Error::InvalidConfiguration),
};
w.write_all(s.as_ref())?;
Ok(())
}
pub fn save<P: AsRef<Path>>(&self, path: P) -> Result<(), Error> {
let file = fs::File::create(path.as_ref())?;
self.save_to(file)
}
pub fn load_from<R: io::Read>(mut r: R) -> Result<Config, Error> {
let mut buf = Vec::new();
r.read_to_end(&mut buf)?;
match toml::from_slice(buf.as_ref()) {
Ok(cfg) => Ok(cfg),
Err(_) => Err(Error::InvalidConfiguration),
}
}
pub fn load<P: AsRef<Path>>(path: P) -> Result<Config, Error> {
let file = fs::File::open(path.as_ref())?;
Self::load_from(file)
}
pub fn use_compression(mut self, use_compression: bool) -> Config {
self.use_compression = use_compression;
self
}
pub fn temporary(mut self, temporary: bool) -> Config {
self.temporary = temporary;
self
}
pub fn flush_every_ms(mut self, ms: u64) -> Config {
self.flush_every_ms = Some(ms);
self
}
pub fn cache_capacity(mut self, bytes: u64) -> Config {
self.cache_capacity = Some(bytes);
self
}
pub fn segment_size(mut self, kb: usize) -> Config {
self.segment_size = Some(kb);
self
}
pub(crate) fn open(&mut self) -> Result<sled::Db, Error> {
let config = sled::Config::new()
.path(&self.path)
.temporary(self.temporary)
.flush_every_ms(self.flush_every_ms)
.use_compression(self.use_compression);
let config = if let Some(cache_capacity) = self.cache_capacity {
config.cache_capacity(cache_capacity)
} else {
config
};
let config = if let Some(segment_size) = self.segment_size {
config.segment_size(segment_size)
} else {
config
};
let db = config.open()?;
Ok(db)
}
}