1pub use crate::error::NihilityConfigError;
2use serde::Serialize;
3use serde::de::DeserializeOwned;
4use std::fs;
5use std::fs::File;
6use std::io::{BufReader, Write};
7use std::path::Path;
8use tracing::debug;
9
10mod error;
11
12const DEFAULT_BASE_PATH: &str = "./config";
13const TOML_SUFFIX: &str = "toml";
14const JSON_SUFFIX: &str = "json";
15
16pub fn get_config<T>(module_name: &str) -> Result<T, NihilityConfigError>
17where
18 T: Serialize + DeserializeOwned + Default,
19{
20 debug!("Loading Module {} Config", module_name);
21 let base_path = option_env!("NIHILITY_CONFIG_PATH").unwrap_or_else(|| DEFAULT_BASE_PATH);
22 init_base_path(base_path)?;
23 let prefix = format!("{}/{}", base_path, module_name);
24 if Path::try_exists(format!("{}.{}", prefix, TOML_SUFFIX).as_ref())?
25 && cfg!(feature = "toml_config")
26 {
27 let toml_str = fs::read_to_string(format!("{}.{}", prefix, TOML_SUFFIX))?;
28 return Ok(toml::from_str(toml_str.as_str())?);
29 } else if Path::try_exists(format!("{}.{}", prefix, JSON_SUFFIX).as_ref())?
30 && cfg!(feature = "json_config")
31 {
32 let reader = BufReader::new(File::open(format!("{}.{}", prefix, JSON_SUFFIX))?);
33 return Ok(serde_json::from_reader(reader)?);
34 } else {
35 let mut config_file: File = File::create(format!("{}.{}", prefix, TOML_SUFFIX))?;
36 config_file.write_all(toml::to_string_pretty(&T::default())?.as_bytes())?;
37 config_file.flush()?;
38 }
39 Ok(T::default())
40}
41
42pub fn set_config<T>(module_name: &str, module_config: &T) -> Result<(), NihilityConfigError>
43where
44 T: Serialize,
45{
46 debug!("Set Module {} Config", module_name);
47 let base_path = option_env!("NIHILITY_CONFIG_PATH").unwrap_or_else(|| DEFAULT_BASE_PATH);
48 init_base_path(base_path)?;
49 let prefix = format!("{}/{}", base_path, module_name);
50 if Path::try_exists(format!("{}.{}", prefix, TOML_SUFFIX).as_ref())?
51 && cfg!(feature = "toml_config")
52 {
53 let mut config_file = File::options().write(true).open(format!("{}.{}", prefix, TOML_SUFFIX))?;
54 config_file.write_all(toml::to_string_pretty(module_config)?.as_bytes())?;
55 config_file.flush()?;
56 } else if Path::try_exists(format!("{}.{}", prefix, JSON_SUFFIX).as_ref())?
57 && cfg!(feature = "json_config")
58 {
59 let mut config_file = File::options().write(true).open(format!("{}.{}", prefix, JSON_SUFFIX))?;
60 config_file.write_all(serde_json::to_string_pretty(module_config)?.as_bytes())?;
61 config_file.flush()?;
62 } else {
63 let mut config_file: File = File::create(format!("{}.{}", prefix, TOML_SUFFIX))?;
64 config_file.write_all(toml::to_string_pretty(module_config)?.as_bytes())?;
65 config_file.flush()?;
66 }
67
68 Ok(())
69}
70
71fn init_base_path<P: AsRef<Path>>(path: P) -> Result<(), NihilityConfigError> {
72 if !Path::try_exists(path.as_ref())? {
73 fs::create_dir_all(path)?;
74 } else if path.as_ref().is_file() {
75 fs::create_dir(path)?;
76 }
77 Ok(())
78}