1use std::collections::{hash_map, HashMap};
7use std::ops::{Index, IndexMut};
8
9#[derive(Debug, Default, Clone, PartialEq, Eq)]
19pub struct Context(HashMap<String, String>);
20
21impl Context {
22 pub fn new() -> Self {
23 Context {
24 ..Default::default()
25 }
26 }
27
28 pub fn var(&self, name: &str) -> Option<&String> {
29 self.0.get(name)
30 }
31
32 pub fn var_mut(&mut self, name: &str) -> Option<&mut String> {
33 self.0.get_mut(name)
34 }
35
36 pub fn set_var(&mut self, name: String, val: String) -> Option<String> {
37 self.0.insert(name, val)
38 }
39
40 pub fn iter_vars(&self) -> hash_map::Iter<'_, String, String> {
41 self.0.iter()
42 }
43
44 pub fn iter_vars_mut(&mut self) -> hash_map::IterMut<'_, String, String> {
45 self.0.iter_mut()
46 }
47}
48
49impl From<std::env::Vars> for Context {
50
51 fn from(vars: std::env::Vars) -> Self {
58 let mut ctx = Context {
59 ..Default::default()
60 };
61 for (name, val) in vars {
62 ctx.set_var(name, val);
63 }
64 ctx
65 }
66}
67
68impl From<HashMap<String, String>> for Context {
69
70 fn from(vars: HashMap<String, String>) -> Self {
79 Context(vars.clone())
80 }
81}
82
83impl From<&Context> for Context {
84 fn from(ctx: &Context) -> Self {
85 ctx.clone()
86 }
87}
88
89impl Index<&str> for Context {
90 type Output = String;
91
92 fn index(&self, index: &str) -> &Self::Output {
93 self.0.index(index)
94 }
95}
96
97impl IndexMut<&str> for Context {
98 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
99 if !self.0.contains_key(index) {
100 self.0.insert(String::from(index), String::new());
101 }
102 self.0.get_mut(index).unwrap()
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn test_context() {
112 let s1 = String::from("one");
113 let i1 = String::from("1");
114 let s2 = String::from("two");
115 let i2 = String::from("2");
116
117 let mut vars = HashMap::new();
118 vars.insert(s1.clone(), i1.clone());
119 let mut ctx = Context::from(vars);
120
121 ctx[&s2] = i2.clone();
122 assert_eq!(ctx[&s1], i1);
123 assert_eq!(ctx[&s2], i2);
124 }
125}