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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
mod parser;
mod substitution;
use std::{
    collections::HashMap,
    fs::File,
    io::{BufRead, BufReader, Lines, Result},
    path::PathBuf,
};

type KeyHash = HashMap<String, String>;

// Just re-exporting to use as a standalone parser
pub use parser::LineParser;
pub use substitution::Substitution;

#[derive(Debug)]
pub struct Zenv {
    path: PathBuf,
    expand: bool,
}

impl Zenv {
    pub fn new(path: PathBuf, expand: bool) -> Self {
        Self { path, expand }
    }

    pub fn read(&self) -> Result<Lines<BufReader<File>>> {
        let file = File::open(&self.path)?;
        let reader = BufReader::new(file);

        Ok(reader.lines())
    }

    pub fn parse(&self) -> Result<KeyHash> {
        let lines = self.read()?;
        let mut hash: KeyHash = HashMap::with_capacity(lines.size_hint().0);

        for line in lines {
            let line = line.expect("Unable to parse line");
            let p = LineParser::parse_line(&line);

            if let Some((key, val)) = p {
                hash.insert(key, val);
            }
        }

        if self.expand {
            Substitution::new(&mut hash).substitute();
        }

        Ok(hash)
    }

    pub fn config(&self) -> Result<()> {
        let vars = self.parse()?;

        for (key, val) in vars {
            std::env::set_var(key, val);
        }

        Ok(())
    }
}