    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37

    use std::error::Error;

    use ini::Ini;

    use crate::map::Map;
    use crate::value::{Value, ValueKind};

    pub fn parse(
        uri: Option<&String>,
        text: &str,
    ) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
        let mut map: Map<String, Value> = Map::new();
        let i = Ini::load_from_str(text)?;
        for (sec, prop) in i.iter() {
            match sec {
                Some(sec) => {
                    let mut sec_map: Map<String, Value> = Map::new();
                    for (k, v) in prop.iter() {
                        sec_map.insert(
                            k.to_owned(),
                            Value::new(uri, ValueKind::String(v.to_owned())),
                        );
                    }
                    map.insert(sec.to_owned(), Value::new(uri, ValueKind::Table(sec_map)));
                }
                None => {
                    for (k, v) in prop.iter() {
                        map.insert(
                            k.to_owned(),
                            Value::new(uri, ValueKind::String(v.to_owned())),
                        );
                    }
                }
            }
        }
        Ok(map)
    }