1use light_ini::{IniError, IniHandler, IniParser};
2use std::{collections::HashMap, env, error, fmt, path::PathBuf};
3
4#[derive(Debug)]
5enum HandlerError {
6 DuplicateSection(String),
7 UnknownSection(String),
8}
9
10impl error::Error for HandlerError {}
11
12impl fmt::Display for HandlerError {
13 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
14 match self {
15 HandlerError::DuplicateSection(name) => write!(fmt, "{}: duplicate section", name),
16 HandlerError::UnknownSection(name) => write!(fmt, "{}: unknown section", name),
17 }
18 }
19}
20
21struct Handler {
22 pub globals: HashMap<String, String>,
23 pub sections: HashMap<String, HashMap<String, String>>,
24 section_name: Option<String>,
25}
26
27impl Handler {
28 fn new() -> Handler {
29 Handler {
30 globals: HashMap::new(),
31 sections: HashMap::new(),
32 section_name: None,
33 }
34 }
35}
36
37impl IniHandler for Handler {
38 type Error = HandlerError;
39
40 fn section(&mut self, name: &str) -> Result<(), Self::Error> {
41 self.section_name = Some(name.to_string());
42 match self.sections.insert(name.to_string(), HashMap::new()) {
43 Some(_) => Err(HandlerError::DuplicateSection(name.to_string())),
44 None => Ok(()),
45 }
46 }
47
48 fn option(&mut self, key: &str, value: &str) -> Result<(), Self::Error> {
49 match &self.section_name {
50 None => {
51 self.globals.insert(key.to_string(), value.to_string());
52 Ok(())
53 }
54 Some(ref section_name) => match self.sections.get_mut(section_name) {
55 Some(ref mut section) => {
56 section.insert(key.to_string(), value.to_string());
57 Ok(())
58 }
59 None => Err(HandlerError::UnknownSection(section_name.to_string())),
60 },
61 }
62 }
63}
64
65struct MainError(IniError<HandlerError>);
66
67impl From<IniError<HandlerError>> for MainError {
68 fn from(err: IniError<HandlerError>) -> Self {
69 Self(err)
70 }
71}
72
73impl fmt::Debug for MainError {
74 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75 write!(f, "{}", self.0)
76 }
77}
78
79fn main() -> Result<(), MainError> {
80 for filename in env::args().skip(1) {
81 let mut handler = Handler::new();
82 let mut parser = IniParser::new(&mut handler);
83 let path = PathBuf::from(&filename);
84 parser.parse_file(path)?;
85 println!("File {}", filename);
86 println!("Globals {:#?}", handler.globals);
87 println!("Sections {:#?}", handler.sections);
88 }
89 Ok(())
90}