roezio/config: Builder pattern

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2022-08-29 21:22:15 +02:00
parent cc19b20469
commit b7bfa835c9

View file

@ -15,13 +15,13 @@
use crate::error::Error;
use std::cell::LazyCell;
use std::collections::HashMap;
use std::fmt;
use std::fs;
use std::io::{BufRead, BufReader, BufWriter, Read, Seek, SeekFrom, Write};
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::sync::LazyLock;
use configparser::ini::Ini;
use jid::Jid;
@ -102,34 +102,60 @@ fn parse_assignment(i: &str) -> IResult<&str, &str> {
Ok((i, key))
}
pub(crate) const DEFAULT_CONFIG: LazyCell<HashMap<&str, HashMap<&str, ConfigValue>>> =
LazyCell::new(|| HashMap::new());
pub(crate) static DEFAULT_CONFIG: LazyLock<HashMap<&str, HashMap<&str, ConfigValue>>> =
LazyLock::new(|| HashMap::new());
pub(crate) struct ConfigBuilder<'a> {
filename: PathBuf,
default_section: Option<&'a str>,
defaults: Option<&'a HashMap<&'a str, HashMap<&'a str, ConfigValue>>>,
}
impl<'a> ConfigBuilder<'a> {
pub(crate) fn with_default_section(mut self, name: &'a str) -> ConfigBuilder<'a> {
self.default_section = Some(name);
self
}
pub(crate) fn with_defaults(
mut self,
defaults: &'a HashMap<&'a str, HashMap<&'a str, ConfigValue>>,
) -> ConfigBuilder<'a> {
self.defaults = Some(defaults);
self
}
/// Builds the Config object
pub(crate) fn build(self) -> Result<Config<'a>, Error> {
let filename: PathBuf = self.filename;
let mut ini = Ini::new();
ini.load::<&Path>(filename.as_ref())
.map_err(|_| Error::UnableToOpenConfigFile(filename.clone()))?;
Ok(Config {
filename,
defaults: self.defaults.unwrap_or(&DEFAULT_CONFIG),
default_section: self.default_section.unwrap_or("Poezio"),
ini: Ini::new(),
})
}
}
#[derive(Debug)]
pub(crate) struct Config<'a> {
filename: PathBuf,
defaults: HashMap<&'a str, HashMap<&'a str, ConfigValue>>,
defaults: &'a HashMap<&'a str, HashMap<&'a str, ConfigValue>>,
default_section: &'a str,
ini: Ini,
}
impl<'a> Config<'a> {
/// Create a new Config object
pub(crate) fn new<P: Into<PathBuf>>(
filename: P,
defaults: HashMap<&'a str, HashMap<&'a str, ConfigValue>>,
default_section: Option<&'a str>,
) -> Result<Self, Error> {
let filename: PathBuf = filename.into();
let mut ini = Ini::new();
ini.load(filename.clone())
.map_err(|_| Error::UnableToOpenConfigFile(filename.clone()))?;
Ok(Config {
filename,
defaults,
default_section: default_section.unwrap_or("default"),
ini: Ini::new(),
})
pub(crate) fn builder<P: Into<PathBuf>>(filename: P) -> ConfigBuilder<'a> {
ConfigBuilder {
filename: filename.into(),
default_section: None,
defaults: None,
}
}
/// Sets a key/value pair in memory and updates the config file.