From b736068ee7b82e05c2ede8bc48ace7ffa4709e29 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Wed, 24 Jul 2024 23:40:11 -0400 Subject: Initial commit. --- backend/src/config.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 backend/src/config.rs (limited to 'backend/src/config.rs') diff --git a/backend/src/config.rs b/backend/src/config.rs new file mode 100644 index 0000000..a1085ba --- /dev/null +++ b/backend/src/config.rs @@ -0,0 +1,82 @@ +use std::collections::hash_map::HashMap; +use std::fs::File; +use std::io::Read; +use std::fmt::{Display, Formatter, Error}; + +#[derive(Clone)] +pub enum ConfigValue { + Str(String), + UInt(usize) +} + +impl Display for ConfigValue { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { + match self { + ConfigValue::Str(s) => write!(f, "{}", s), + ConfigValue::UInt(u) => write!(f, "{}", u) + } + } +} + +struct ConfigItem { + default_value: ConfigValue, + parse_func: Box Option>, +} + +pub struct Config { + v: HashMap, +} + +fn stripped_str(s: String) -> Option { + Some(ConfigValue::Str(String::from(s.trim()))) +} + +fn parse_usize(s: String) -> Option { + if let Ok(r) = usize::from_str_radix(&s, 10) { + Some(ConfigValue::UInt(r)) + } else { None } +} + +pub fn split_at_first<'a, 'b>(s: &'a str, sp: &'b str) -> (&'a str, &'a str) { + if let Some(p) = s.find(sp) { + (&s[.. p], &s[p + sp.len()..]) + } else { (s, "") } +} + +impl Config { + fn items() -> HashMap<&'static str, ConfigItem> { + HashMap::from([ + ("SERVED_DATA_ROOT", ConfigItem{default_value: ConfigValue::Str(String::from("")), parse_func: Box::new(stripped_str)}), + ("POSTS_PER_PAGE", ConfigItem{default_value: ConfigValue::UInt(20), parse_func: Box::new(parse_usize)}), + ("DISPLAY_TIMEZONE", ConfigItem{default_value: ConfigValue::Str(String::from("UTC")), parse_func: Box::new(stripped_str)}), + ("VERSION_STRING", ConfigItem{default_value: ConfigValue::Str(String::from("1.0")), parse_func: Box::new(stripped_str)}), + ]) + } + pub fn parse_config(filename: &str) -> Config { + let mut v = HashMap::from_iter( + Config::items().iter() + .map(|(k, v)| {(String::from(*k), v.default_value.clone())}) + ); + let mut f = File::open(filename).unwrap(); + let mut s = String::new(); + if let Ok(_) = f.read_to_string(&mut s) { + for l in s.split("\n") { + let (sname, svalue) = split_at_first(l, "="); + if let Some(ConfigItem{default_value: _, parse_func}) = Config::items().get(sname) { + if let Some(value) = parse_func(String::from(svalue)) { + v.insert(String::from(sname), value); + } + } + } + } + Config { v } + } + pub fn get(&self, key: &str) -> ConfigValue { + self.v.get(&String::from(key)).unwrap().clone() + } + pub fn get_str(&self, key: &str) -> String { + if let ConfigValue::Str(s) = self.get(key) { + s + } else { String::from("") } + } +} -- cgit v1.2.3