1use crate::{pascal_case, path, Error, FileSource, Result, Settings};
2use configparser::ini::Ini;
3use tokens::{ChangeToken, FileChangeToken, NeverChangeToken};
4
5pub struct Provider(FileSource);
7
8impl Provider {
9 #[inline]
15 pub fn new(file: FileSource) -> Self {
16 Self(file)
17 }
18}
19
20impl crate::Provider for Provider {
21 #[inline]
22 fn name(&self) -> &str {
23 path::provider(&self.0.path, "Ini")
24 }
25
26 fn reload_token(&self) -> Box<dyn ChangeToken> {
27 if self.0.reload_on_change {
28 Box::new(FileChangeToken::new(self.0.path.clone()))
29 } else {
30 Box::new(NeverChangeToken)
31 }
32 }
33
34 fn load(&self, settings: &mut Settings) -> Result {
35 if !self.0.path.is_file() {
36 if self.0.optional {
37 return Ok(());
38 } else {
39 return Err(Error::MissingFile(self.0.path.clone()));
40 }
41 }
42
43 let mut ini = Ini::new_cs();
44 let sections = ini.load(&self.0.path).map_err(Error::Custom)?;
45
46 for (section, pairs) in sections {
47 for (key, value) in pairs {
48 let key = format!("{}{}{}", pascal_case(§ion), path::delimiter(), pascal_case(&key),);
49 settings.insert(key, value.unwrap_or_default());
50 }
51 }
52
53 Ok(())
54 }
55}