aboutsummaryrefslogtreecommitdiff
path: root/src/executor.rs
blob: ef97acebd2a2e4a3ae6cf5520a150b77bd34ff0e (plain)
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::barbfile::{BarbFile, Header};

use std::collections::HashMap;
use ureq;

pub struct Context {
    vars: HashMap<String, String>,
}

impl Context {
    pub fn new<I>(vars: I) -> Context
    where
        I: Iterator<Item = (String, String)>,
    {
        let mut toto = HashMap::new();
        toto.extend(vars);

        Context { vars: toto }
    }

    pub fn empty() -> Context {
        Context {
            vars: HashMap::new(),
        }
    }

    // Preserved for future reference
    // pub fn get_var(&self, name: String) -> Option<String> {
    //     self.vars
    //         .get(&name)
    //         .map(|val| val.clone())
    //         .or_else(|| env::var(name).ok())
    // }

    fn key_str(&self, key: &String) -> String {
        format!("{{{}}}", key)
    }

    pub fn substitute(&self, string: &String) -> String {
        let mut buffer = string.clone();
        for (key, val) in self.vars.iter() {
            buffer = buffer.replace(self.key_str(key).as_str(), val);
        }

        buffer
    }
}

pub struct Executor {
    context: Context,
}

impl Executor {
    pub fn new(context: Context) -> Executor {
        Executor { context }
    }

    pub fn execute(&mut self, bfile: BarbFile) -> Result<ureq::Response, String> {
        let mut req = ureq::request(
            bfile.method_as_string().as_str(),
            self.context.substitute(&bfile.url()).as_str(),
        );

        for header in bfile.headers() {
            req = req.set(
                header.name(),
                self.context.substitute(header.value()).as_str(),
            );
            println!(
                "{} {}",
                header.name(),
                self.context.substitute(header.value())
            );
        }

        match bfile.method().takes_body() {
            true => match bfile.body() {
                Some(body) => req.send_string(body.as_str()),
                None => req.call(),
            },
            false => req.call(),
        }
        .map_err(|_| String::from("Error"))
    }
}

// TODO: tests
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_context_key_str() {
        let ctx = Context::empty();
        assert_eq!(ctx.key_str(&String::from("foo")), String::from("{foo}"));
    }

    #[test]
    fn test_context_substitute() {
        let vars: Vec<(String, String)> = vec![
            (String::from("foo"), String::from("bar")),
            (String::from("bar"), String::from("baz")),
        ];
        let ctx = Context::new(vars.into_iter());
        assert_eq!(
            ctx.substitute(&String::from("blah blah {foo} blah")),
            String::from("blah blah bar blah")
        );
        assert_eq!(
            ctx.substitute(&String::from("blah {foo} {bar} blah")),
            String::from("blah bar baz blah")
        );
    }
}