diff --git a/src/config.rs b/src/config.rs index 4e651759..4d43f2b5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -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>> = - LazyCell::new(|| HashMap::new()); +pub(crate) static DEFAULT_CONFIG: LazyLock>> = + 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, 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>( - filename: P, - defaults: HashMap<&'a str, HashMap<&'a str, ConfigValue>>, - default_section: Option<&'a str>, - ) -> Result { - 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>(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.