hashmap/
hashmap.rs

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}