1use std::collections::HashMap;
2use std::env;
3use std::io::{BufReader, Lines};
4use std::io::prelude::*;
5
6use crate::errors::*;
7use crate::parse;
8
9pub struct Iter<R> {
10 lines: Lines<BufReader<R>>,
11 substitution_data: HashMap<String, Option<String>>,
12}
13
14impl<R: Read> Iter<R> {
15 pub fn new(reader: R) -> Iter<R> {
16 Iter {
17 lines: BufReader::new(reader).lines(),
18 substitution_data: HashMap::new(),
19 }
20 }
21
22 pub fn load(self) -> Result<()> {
23 for item in self {
24 let (key, value) = item?;
25 if env::var(&key).is_err() {
26 env::set_var(&key, value);
27 }
28 }
29
30 Ok(())
31 }
32}
33
34impl<R: Read> Iterator for Iter<R> {
35 type Item = Result<(String, String)>;
36
37 fn next(&mut self) -> Option<Self::Item> {
38 loop {
39 let line = match self.lines.next() {
40 Some(Ok(line)) => line,
41 Some(Err(err)) => return Some(Err(Error::Io(err))),
42 None => return None,
43 };
44
45 match parse::parse_line(&line, &mut self.substitution_data) {
46 Ok(Some(result)) => return Some(Ok(result)),
47 Ok(None) => {}
48 Err(err) => return Some(Err(err)),
49 }
50 }
51 }
52}