rair_env/
environment.rs

1/*
2 * environment.rs: Linking all rair configuration parts together into place.
3 * Copyright (C) 2019  Oddcoder
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17use super::err::*;
18use super::metadata::*;
19use std::collections::HashMap;
20use std::mem;
21#[derive(PartialEq, Debug)]
22pub enum EnvData<'a> {
23    Str(&'a str),
24    U64(u64),
25    I64(i64),
26    Bool(bool),
27    Color(u8, u8, u8),
28}
29impl<'a, T> From<&'a EnvMetaData<T>> for EnvData<'a> {
30    fn from(meta: &'a EnvMetaData<T>) -> Self {
31        match meta {
32            EnvMetaData::Str(s) => EnvData::Str(&s.data),
33            EnvMetaData::I64(i) => EnvData::I64(i.data),
34            EnvMetaData::U64(u) => EnvData::U64(u.data),
35            EnvMetaData::Bool(u) => EnvData::Bool(u.data),
36            EnvMetaData::Color(c) => EnvData::Color(c.data.0, c.data.1, c.data.2),
37        }
38    }
39}
40#[derive(Default)]
41pub struct Environment<T> {
42    data: HashMap<String, EnvMetaData<T>>,
43}
44
45impl<T> Environment<T> {
46    pub fn new() -> Self {
47        Environment { data: HashMap::new() }
48    }
49    // All exec_*_cb function are guaranteed to be running on the correct type
50    fn exec_str_cb(&self, key: &str, data: &mut T) -> bool {
51        let meta = self.data.get(key).unwrap().as_str().unwrap();
52        let val = &meta.data;
53        if let Some(cb) = meta.cb {
54            return cb(key, val, self, data);
55        }
56        return true;
57    }
58
59    pub fn add_str_with_cb(&mut self, key: &str, val: &str, help: &str, data: &mut T, cb: StrFn<T>) -> Result<(), EnvErr> {
60        if self.data.contains_key(key) {
61            return Err(EnvErr::AlreadyExist);
62        }
63        let meta = EnvStr {
64            data: val.to_string(),
65            default: val.to_string(),
66            help: help.to_string(),
67            cb: Some(cb),
68        };
69        self.data.insert(key.to_string(), EnvMetaData::Str(meta));
70        if !self.exec_str_cb(key, data) {
71            self.data.remove(key).unwrap();
72            return Err(EnvErr::CbFailed);
73        }
74        return Ok(());
75    }
76
77    pub fn add_str(&mut self, key: &str, val: &str, help: &str) -> Result<(), EnvErr> {
78        if self.data.contains_key(key) {
79            return Err(EnvErr::AlreadyExist);
80        }
81        let meta = EnvStr {
82            data: val.to_string(),
83            default: val.to_string(),
84            help: help.to_string(),
85            cb: None,
86        };
87        self.data.insert(key.to_string(), EnvMetaData::Str(meta));
88        return Ok(());
89    }
90
91    pub fn get_str(&self, key: &str) -> Result<&str, EnvErr> {
92        let meta = match self.data.get(key) {
93            Some(meta) => meta,
94            None => return Err(EnvErr::NotFound),
95        };
96        match meta.as_str() {
97            Some(s) => return Ok(&s.data),
98            None => return Err(EnvErr::DifferentType),
99        };
100    }
101
102    pub fn set_str(&mut self, key: &str, value: &str, data: &mut T) -> Result<(), EnvErr> {
103        let meta = match self.data.get_mut(key) {
104            Some(meta) => meta,
105            None => return Err(EnvErr::NotFound),
106        };
107        let mut tmp = value.to_string();
108        if let Some(s) = meta.mut_str() {
109            mem::swap(&mut tmp, &mut s.data);
110            if !self.exec_str_cb(key, data) {
111                //restore old data
112                let meta = self.data.get_mut(key).unwrap();
113                let s = meta.mut_str().unwrap();
114                mem::swap(&mut s.data, &mut tmp);
115                return Err(EnvErr::CbFailed);
116            }
117            return Ok(());
118        } else {
119            return Err(EnvErr::DifferentType);
120        }
121    }
122
123    pub fn is_str(&self, key: &str) -> bool {
124        let meta = match self.data.get(key) {
125            Some(meta) => meta,
126            None => return false,
127        };
128        return meta.as_str().is_some();
129    }
130
131    fn exec_u64_cb(&self, key: &str, data: &mut T) -> bool {
132        let meta = self.data.get(key).unwrap().as_u64().unwrap();
133        if let Some(cb) = meta.cb {
134            return cb(key, meta.data, self, data);
135        }
136        return true;
137    }
138
139    pub fn add_u64_with_cb(&mut self, key: &str, val: u64, help: &str, data: &mut T, cb: U64Fn<T>) -> Result<(), EnvErr> {
140        if self.data.contains_key(key) {
141            return Err(EnvErr::AlreadyExist);
142        }
143        let meta = EnvU64 {
144            data: val,
145            default: val,
146            help: help.to_string(),
147            cb: Some(cb),
148        };
149        self.data.insert(key.to_string(), EnvMetaData::U64(meta));
150        if !self.exec_u64_cb(key, data) {
151            self.data.remove(key).unwrap();
152            return Err(EnvErr::CbFailed);
153        }
154        return Ok(());
155    }
156
157    pub fn add_u64(&mut self, key: &str, val: u64, help: &str) -> Result<(), EnvErr> {
158        if self.data.contains_key(key) {
159            return Err(EnvErr::AlreadyExist);
160        }
161        let meta = EnvU64 {
162            data: val,
163            default: val,
164            help: help.to_string(),
165            cb: None,
166        };
167        self.data.insert(key.to_string(), EnvMetaData::U64(meta));
168        return Ok(());
169    }
170
171    pub fn get_u64(&self, key: &str) -> Result<u64, EnvErr> {
172        let meta = match self.data.get(key) {
173            Some(meta) => meta,
174            None => return Err(EnvErr::NotFound),
175        };
176        match meta.as_u64() {
177            Some(s) => return Ok(s.data),
178            None => return Err(EnvErr::DifferentType),
179        };
180    }
181
182    pub fn set_u64(&mut self, key: &str, value: u64, data: &mut T) -> Result<(), EnvErr> {
183        let meta = match self.data.get_mut(key) {
184            Some(meta) => meta,
185            None => return Err(EnvErr::NotFound),
186        };
187        let mut tmp = value;
188        if let Some(s) = meta.mut_u64() {
189            mem::swap(&mut tmp, &mut s.data);
190            if !self.exec_u64_cb(key, data) {
191                //restore old data
192                let meta = self.data.get_mut(key).unwrap();
193                let s = meta.mut_u64().unwrap();
194                mem::swap(&mut s.data, &mut tmp);
195                return Err(EnvErr::CbFailed);
196            }
197            return Ok(());
198        } else {
199            return Err(EnvErr::DifferentType);
200        }
201    }
202
203    pub fn is_u64(&self, key: &str) -> bool {
204        let meta = match self.data.get(key) {
205            Some(meta) => meta,
206            None => return false,
207        };
208        return meta.as_u64().is_some();
209    }
210
211    fn exec_i64_cb(&self, key: &str, data: &mut T) -> bool {
212        let meta = self.data.get(key).unwrap().as_i64().unwrap();
213        if let Some(cb) = meta.cb {
214            return cb(key, meta.data, self, data);
215        }
216        return true;
217    }
218
219    pub fn add_i64_with_cb(&mut self, key: &str, val: i64, help: &str, data: &mut T, cb: I64Fn<T>) -> Result<(), EnvErr> {
220        if self.data.contains_key(key) {
221            return Err(EnvErr::AlreadyExist);
222        }
223        let meta = EnvI64 {
224            data: val,
225            default: val,
226            help: help.to_string(),
227            cb: Some(cb),
228        };
229        self.data.insert(key.to_string(), EnvMetaData::I64(meta));
230        if !self.exec_i64_cb(key, data) {
231            self.data.remove(key).unwrap();
232            return Err(EnvErr::CbFailed);
233        }
234        return Ok(());
235    }
236
237    pub fn add_i64(&mut self, key: &str, val: i64, help: &str) -> Result<(), EnvErr> {
238        if self.data.contains_key(key) {
239            return Err(EnvErr::AlreadyExist);
240        }
241        let meta = EnvI64 {
242            data: val,
243            default: val,
244            help: help.to_string(),
245            cb: None,
246        };
247        self.data.insert(key.to_string(), EnvMetaData::I64(meta));
248        return Ok(());
249    }
250
251    pub fn get_i64(&self, key: &str) -> Result<i64, EnvErr> {
252        let meta = match self.data.get(key) {
253            Some(meta) => meta,
254            None => return Err(EnvErr::NotFound),
255        };
256        match meta.as_i64() {
257            Some(s) => return Ok(s.data),
258            None => return Err(EnvErr::DifferentType),
259        };
260    }
261
262    pub fn set_i64(&mut self, key: &str, value: i64, data: &mut T) -> Result<(), EnvErr> {
263        let meta = match self.data.get_mut(key) {
264            Some(meta) => meta,
265            None => return Err(EnvErr::NotFound),
266        };
267        let mut tmp = value;
268        if let Some(s) = meta.mut_i64() {
269            mem::swap(&mut tmp, &mut s.data);
270            if !self.exec_i64_cb(key, data) {
271                //restore old data
272                let meta = self.data.get_mut(key).unwrap();
273                let s = meta.mut_i64().unwrap();
274                mem::swap(&mut s.data, &mut tmp);
275                return Err(EnvErr::CbFailed);
276            }
277            return Ok(());
278        } else {
279            return Err(EnvErr::DifferentType);
280        }
281    }
282
283    pub fn is_i64(&self, key: &str) -> bool {
284        let meta = match self.data.get(key) {
285            Some(meta) => meta,
286            None => return false,
287        };
288        return meta.as_i64().is_some();
289    }
290
291    fn exec_bool_cb(&self, key: &str, data: &mut T) -> bool {
292        let meta = self.data.get(key).unwrap().as_bool().unwrap();
293        if let Some(cb) = meta.cb {
294            return cb(key, meta.data, self, data);
295        }
296        return true;
297    }
298
299    pub fn add_bool_with_cb(&mut self, key: &str, val: bool, help: &str, data: &mut T, cb: BoolFn<T>) -> Result<(), EnvErr> {
300        if self.data.contains_key(key) {
301            return Err(EnvErr::AlreadyExist);
302        }
303        let meta = EnvBool {
304            data: val,
305            default: val,
306            help: help.to_string(),
307            cb: Some(cb),
308        };
309        self.data.insert(key.to_string(), EnvMetaData::Bool(meta));
310        if !self.exec_bool_cb(key, data) {
311            self.data.remove(key).unwrap();
312            return Err(EnvErr::CbFailed);
313        }
314        return Ok(());
315    }
316
317    pub fn add_bool(&mut self, key: &str, val: bool, help: &str) -> Result<(), EnvErr> {
318        if self.data.contains_key(key) {
319            return Err(EnvErr::AlreadyExist);
320        }
321        let meta = EnvBool {
322            data: val,
323            default: val,
324            help: help.to_string(),
325            cb: None,
326        };
327        self.data.insert(key.to_string(), EnvMetaData::Bool(meta));
328        return Ok(());
329    }
330
331    pub fn get_bool(&self, key: &str) -> Result<bool, EnvErr> {
332        let meta = match self.data.get(key) {
333            Some(meta) => meta,
334            None => return Err(EnvErr::NotFound),
335        };
336        match meta.as_bool() {
337            Some(s) => return Ok(s.data),
338            None => return Err(EnvErr::DifferentType),
339        };
340    }
341
342    pub fn set_bool(&mut self, key: &str, value: bool, data: &mut T) -> Result<(), EnvErr> {
343        let meta = match self.data.get_mut(key) {
344            Some(meta) => meta,
345            None => return Err(EnvErr::NotFound),
346        };
347        let mut tmp = value;
348        if let Some(s) = meta.mut_bool() {
349            mem::swap(&mut tmp, &mut s.data);
350            if !self.exec_bool_cb(key, data) {
351                //restore old data
352                let meta = self.data.get_mut(key).unwrap();
353                let s = meta.mut_bool().unwrap();
354                mem::swap(&mut s.data, &mut tmp);
355                return Err(EnvErr::CbFailed);
356            }
357            return Ok(());
358        } else {
359            return Err(EnvErr::DifferentType);
360        }
361    }
362
363    pub fn is_bool(&self, key: &str) -> bool {
364        let meta = match self.data.get(key) {
365            Some(meta) => meta,
366            None => return false,
367        };
368        return meta.as_bool().is_some();
369    }
370
371    fn exec_color_cb(&self, key: &str, data: &mut T) -> bool {
372        let meta = self.data.get(key).unwrap().as_color().unwrap();
373        if let Some(cb) = meta.cb {
374            return cb(key, meta.data, self, data);
375        }
376        return true;
377    }
378
379    pub fn add_color_with_cb(&mut self, key: &str, val: (u8, u8, u8), help: &str, data: &mut T, cb: ColorFn<T>) -> Result<(), EnvErr> {
380        if self.data.contains_key(key) {
381            return Err(EnvErr::AlreadyExist);
382        }
383        let meta = EnvColor {
384            data: val,
385            default: val,
386            help: help.to_string(),
387            cb: Some(cb),
388        };
389        self.data.insert(key.to_string(), EnvMetaData::Color(meta));
390        if !self.exec_color_cb(key, data) {
391            self.data.remove(key).unwrap();
392            return Err(EnvErr::CbFailed);
393        }
394        return Ok(());
395    }
396
397    pub fn add_color(&mut self, key: &str, val: (u8, u8, u8), help: &str) -> Result<(), EnvErr> {
398        if self.data.contains_key(key) {
399            return Err(EnvErr::AlreadyExist);
400        }
401        let meta = EnvColor {
402            data: val,
403            default: val,
404            help: help.to_string(),
405            cb: None,
406        };
407        self.data.insert(key.to_string(), EnvMetaData::Color(meta));
408        return Ok(());
409    }
410
411    pub fn get_color(&self, key: &str) -> Result<(u8, u8, u8), EnvErr> {
412        let meta = match self.data.get(key) {
413            Some(meta) => meta,
414            None => return Err(EnvErr::NotFound),
415        };
416        match meta.as_color() {
417            Some(s) => return Ok(s.data),
418            None => return Err(EnvErr::DifferentType),
419        };
420    }
421
422    pub fn set_color(&mut self, key: &str, value: (u8, u8, u8), data: &mut T) -> Result<(), EnvErr> {
423        let meta = match self.data.get_mut(key) {
424            Some(meta) => meta,
425            None => return Err(EnvErr::NotFound),
426        };
427        let mut tmp = value;
428        if let Some(s) = meta.mut_color() {
429            mem::swap(&mut tmp, &mut s.data);
430            if !self.exec_color_cb(key, data) {
431                //restore old data
432                let meta = self.data.get_mut(key).unwrap();
433                let s = meta.mut_color().unwrap();
434                mem::swap(&mut s.data, &mut tmp);
435                return Err(EnvErr::CbFailed);
436            }
437            return Ok(());
438        } else {
439            return Err(EnvErr::DifferentType);
440        }
441    }
442
443    pub fn is_color(&self, key: &str) -> bool {
444        let meta = match self.data.get(key) {
445            Some(meta) => meta,
446            None => return false,
447        };
448        return meta.as_color().is_some();
449    }
450
451    pub fn reset(&mut self, key: &str, data: &mut T) -> Result<(), EnvErr> {
452        let meta = match self.data.get_mut(key) {
453            Some(meta) => meta,
454            None => return Err(EnvErr::NotFound),
455        };
456        match meta {
457            EnvMetaData::Bool(b) => {
458                b.data = b.default;
459                self.exec_bool_cb(key, data);
460            }
461            EnvMetaData::Color(c) => {
462                c.data = c.default;
463                self.exec_color_cb(key, data);
464            }
465            EnvMetaData::I64(i) => {
466                i.data = i.default;
467                self.exec_i64_cb(key, data);
468            }
469            EnvMetaData::U64(u) => {
470                u.data = u.default;
471                self.exec_u64_cb(key, data);
472            }
473            EnvMetaData::Str(s) => {
474                s.data = s.default.clone();
475                self.exec_str_cb(key, data);
476            }
477        }
478        return Ok(());
479    }
480    pub fn get(&self, key: &str) -> Option<EnvData> {
481        let meta = self.data.get(key)?;
482        return match meta {
483            EnvMetaData::Bool(b) => Some(EnvData::Bool(b.data)),
484            EnvMetaData::I64(i) => Some(EnvData::I64(i.data)),
485            EnvMetaData::U64(u) => Some(EnvData::U64(u.data)),
486            EnvMetaData::Str(s) => Some(EnvData::Str(&s.data)),
487            EnvMetaData::Color(c) => Some(EnvData::Color(c.data.0, c.data.1, c.data.2)),
488        };
489    }
490    pub fn get_help(&self, key: &str) -> Option<&str> {
491        let meta = self.data.get(key)?;
492        return match meta {
493            EnvMetaData::Bool(b) => Some(&b.help),
494            EnvMetaData::I64(i) => Some(&i.help),
495            EnvMetaData::U64(u) => Some(&u.help),
496            EnvMetaData::Str(s) => Some(&s.help),
497            EnvMetaData::Color(c) => Some(&c.help),
498        };
499    }
500    pub fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = (&str, EnvData)> + 'a> {
501        return Box::new(self.data.iter().map(|(k, v)| (k.as_str(), EnvData::from(v))));
502    }
503}
504
505#[cfg(test)]
506mod test_environment {
507    use super::*;
508    fn even_str(_: &str, value: &str, _: &Environment<Option<()>>, _: &mut Option<()>) -> bool {
509        return value.len() % 2 == 0;
510    }
511    fn even_u64(_: &str, value: u64, _: &Environment<Option<()>>, _: &mut Option<()>) -> bool {
512        return value % 2 == 0;
513    }
514    fn negative_i64(_: &str, value: i64, _: &Environment<Option<()>>, _: &mut Option<()>) -> bool {
515        return value < 0;
516    }
517    fn always_false(_: &str, value: bool, _: &Environment<Option<()>>, _: &mut Option<()>) -> bool {
518        return !value;
519    }
520    fn grayscale(_: &str, color: (u8, u8, u8), _: &Environment<Option<()>>, _: &mut Option<()>) -> bool {
521        let (r, g, b) = color;
522        return r == g && g == b;
523    }
524    fn prep_env() -> Environment<Option<()>> {
525        let mut data = None;
526        let mut env = Environment::new();
527        env.add_str("s1", "value1", "First String").unwrap();
528        env.add_str_with_cb("s2", "value2", "Second String", &mut data, even_str).unwrap();
529        env.add_u64("u1", 1, "First U64").unwrap();
530        env.add_u64_with_cb("u2", 2, "Second U64", &mut data, even_u64).unwrap();
531        env.add_i64("i1", 1, "First I64").unwrap();
532        env.add_i64_with_cb("i2", -1, "Second I64", &mut data, negative_i64).unwrap();
533        env.add_bool("b1", true, "First Bool").unwrap();
534        env.add_bool_with_cb("b2", false, "Second Bool", &mut data, always_false).unwrap();
535        env.add_color("c1", (31, 33, 37), "First Color").unwrap();
536        env.add_color_with_cb("c2", (50, 50, 50), "Second Color", &mut data, grayscale).unwrap();
537        return env;
538    }
539    #[test]
540    fn test_str() {
541        let mut env = prep_env();
542        let mut data = None;
543        assert_eq!(env.add_str_with_cb("s03", "value02", "", &mut data, even_str).err().unwrap(), EnvErr::CbFailed);
544        assert_eq!(env.add_str("s1", "v3", "").err().unwrap(), EnvErr::AlreadyExist);
545        assert_eq!(env.add_str_with_cb("s1", "value1", "", &mut data, even_str).err().unwrap(), EnvErr::AlreadyExist);
546        assert_eq!(env.is_str("s1"), true);
547        assert_eq!(env.is_str("u1"), false);
548        assert_eq!(env.is_str("s3"), false);
549        assert_eq!(env.get_str("s1").unwrap(), "value1");
550        assert_eq!(env.get_str("s2").unwrap(), "value2");
551        assert_eq!(env.get_str("s3").err().unwrap(), EnvErr::NotFound);
552        assert_eq!(env.get_str("u1").err().unwrap(), EnvErr::DifferentType);
553        env.set_str("s1", "newvalue1", &mut data).unwrap();
554        assert_eq!(env.get_str("s1").unwrap(), "newvalue1");
555        env.set_str("s2", "newvalue02", &mut data).unwrap();
556        assert_eq!(env.get_str("s2").unwrap(), "newvalue02");
557        assert_eq!(env.set_str("s2", "tmp", &mut data).err().unwrap(), EnvErr::CbFailed);
558        assert_eq!(env.get_str("s2").unwrap(), "newvalue02");
559        assert_eq!(env.set_str("s3", "tmp", &mut data).err().unwrap(), EnvErr::NotFound);
560        assert_eq!(env.set_str("u1", "tmp", &mut data).err().unwrap(), EnvErr::DifferentType);
561        assert_eq!(env.get("s1").unwrap(), EnvData::Str("newvalue1"));
562        assert_eq!(env.get("s3"), None);
563        env.reset("s1", &mut data).unwrap();
564        assert_eq!(env.get_str("s1").unwrap(), "value1");
565        assert_eq!(env.reset("s3", &mut data).err().unwrap(), EnvErr::NotFound);
566        assert_eq!(env.get_help("s3"), None);
567        assert_eq!(env.get_help("s1").unwrap(), "First String");
568    }
569    #[test]
570    fn test_u64() {
571        let mut env = prep_env();
572        let mut data = None;
573        assert_eq!(env.add_u64_with_cb("u3", 3, "", &mut data, even_u64).err().unwrap(), EnvErr::CbFailed);
574        assert_eq!(env.add_u64("u2", 5, "").err().unwrap(), EnvErr::AlreadyExist);
575        assert_eq!(env.add_u64_with_cb("s1", 4, "", &mut data, even_u64).err().unwrap(), EnvErr::AlreadyExist);
576        assert_eq!(env.is_u64("u1"), true);
577        assert_eq!(env.is_u64("s1"), false);
578        assert_eq!(env.is_u64("u3"), false);
579        assert_eq!(env.get_u64("u1").unwrap(), 1);
580        assert_eq!(env.get_u64("u2").unwrap(), 2);
581        assert_eq!(env.get_u64("u3").err().unwrap(), EnvErr::NotFound);
582        assert_eq!(env.get_u64("s1").err().unwrap(), EnvErr::DifferentType);
583        env.set_u64("u1", 8, &mut data).unwrap();
584        assert_eq!(env.get_u64("u1").unwrap(), 8);
585        env.set_u64("u2", 4, &mut data).unwrap();
586        assert_eq!(env.get_u64("u2").unwrap(), 4);
587        assert_eq!(env.set_u64("u2", 7, &mut data).err().unwrap(), EnvErr::CbFailed);
588        assert_eq!(env.get_u64("u2").unwrap(), 4);
589        assert_eq!(env.set_u64("u3", 5, &mut data).err().unwrap(), EnvErr::NotFound);
590        assert_eq!(env.set_u64("s1", 3, &mut data).err().unwrap(), EnvErr::DifferentType);
591        assert_eq!(env.get("u1").unwrap(), EnvData::U64(8));
592        env.reset("u1", &mut data).unwrap();
593        assert_eq!(env.get_u64("u1").unwrap(), 1);
594        assert_eq!(env.get_help("u1").unwrap(), "First U64");
595    }
596    #[test]
597    fn test_i64() {
598        let mut env = prep_env();
599        let mut data = None;
600        assert_eq!(env.add_i64_with_cb("i3", 3, "", &mut data, negative_i64).err().unwrap(), EnvErr::CbFailed);
601        assert_eq!(env.add_i64("i2", 5, "").err().unwrap(), EnvErr::AlreadyExist);
602        assert_eq!(env.add_i64_with_cb("s1", 4, "", &mut data, negative_i64).err().unwrap(), EnvErr::AlreadyExist);
603        assert_eq!(env.is_i64("i1"), true);
604        assert_eq!(env.is_i64("u1"), false);
605        assert_eq!(env.is_i64("i3"), false);
606        assert_eq!(env.get_i64("i1").unwrap(), 1);
607        assert_eq!(env.get_i64("i2").unwrap(), -1);
608        assert_eq!(env.get_i64("u3").err().unwrap(), EnvErr::NotFound);
609        assert_eq!(env.get_i64("s1").err().unwrap(), EnvErr::DifferentType);
610        env.set_i64("i1", 8, &mut data).unwrap();
611        assert_eq!(env.get_i64("i1").unwrap(), 8);
612        env.set_i64("i2", -4, &mut data).unwrap();
613        assert_eq!(env.get_i64("i2").unwrap(), -4);
614        assert_eq!(env.set_i64("i2", 7, &mut data).err().unwrap(), EnvErr::CbFailed);
615        assert_eq!(env.get_i64("i2").unwrap(), -4);
616        assert_eq!(env.set_i64("i3", 5, &mut data).err().unwrap(), EnvErr::NotFound);
617        assert_eq!(env.set_i64("s1", 3, &mut data).err().unwrap(), EnvErr::DifferentType);
618        assert_eq!(env.get("i1").unwrap(), EnvData::I64(8));
619        env.reset("i1", &mut data).unwrap();
620        assert_eq!(env.get_i64("i1").unwrap(), 1);
621        assert_eq!(env.get_help("i1").unwrap(), "First I64");
622    }
623    #[test]
624    fn test_bool() {
625        let mut env = prep_env();
626        let mut data = None;
627        assert_eq!(env.add_bool_with_cb("b3", true, "", &mut data, always_false).err().unwrap(), EnvErr::CbFailed);
628        assert_eq!(env.add_bool("b2", true, "").err().unwrap(), EnvErr::AlreadyExist);
629        assert_eq!(env.add_bool_with_cb("b1", false, "", &mut data, always_false).err().unwrap(), EnvErr::AlreadyExist);
630        assert_eq!(env.is_bool("b1"), true);
631        assert_eq!(env.is_bool("u1"), false);
632        assert_eq!(env.is_bool("b3"), false);
633        assert_eq!(env.get_bool("b1").unwrap(), true);
634        assert_eq!(env.get_bool("b2").unwrap(), false);
635        assert_eq!(env.get_bool("u3").err().unwrap(), EnvErr::NotFound);
636        assert_eq!(env.get_bool("s1").err().unwrap(), EnvErr::DifferentType);
637        env.set_bool("b1", false, &mut data).unwrap();
638        assert_eq!(env.get_bool("b1").unwrap(), false);
639        assert_eq!(env.set_bool("b2", true, &mut data).err().unwrap(), EnvErr::CbFailed);
640        assert_eq!(env.get_bool("b2").unwrap(), false);
641        assert_eq!(env.set_bool("b3", true, &mut data).err().unwrap(), EnvErr::NotFound);
642        assert_eq!(env.set_bool("s1", false, &mut data).err().unwrap(), EnvErr::DifferentType);
643        assert_eq!(env.get("b1").unwrap(), EnvData::Bool(false));
644        env.reset("b1", &mut data).unwrap();
645        assert_eq!(env.get_bool("b1").unwrap(), true);
646        assert_eq!(env.get_help("b1").unwrap(), "First Bool");
647    }
648
649    #[test]
650    fn test_color() {
651        let mut env = prep_env();
652        let mut data = None;
653        assert_eq!(env.add_color_with_cb("c3", (50, 60, 70), "", &mut data, grayscale).err().unwrap(), EnvErr::CbFailed);
654        assert_eq!(env.add_color("c2", (20, 30, 40), "").err().unwrap(), EnvErr::AlreadyExist);
655        assert_eq!(env.add_color_with_cb("c1", (100, 100, 100), "", &mut data, grayscale).err().unwrap(), EnvErr::AlreadyExist);
656        assert_eq!(env.is_color("c1"), true);
657        assert_eq!(env.is_color("u1"), false);
658        assert_eq!(env.is_color("c3"), false);
659        /**/
660        assert_eq!(env.get_color("c1").unwrap(), (31, 33, 37));
661        assert_eq!(env.get_color("c2").unwrap(), (50, 50, 50));
662        assert_eq!(env.get_color("c3").err().unwrap(), EnvErr::NotFound);
663        assert_eq!(env.get_color("s1").err().unwrap(), EnvErr::DifferentType);
664        env.set_color("c1", (20, 40, 60), &mut data).unwrap();
665        assert_eq!(env.get_color("c1").unwrap(), (20, 40, 60));
666        assert_eq!(env.set_color("c2", (5, 10, 15), &mut data).err().unwrap(), EnvErr::CbFailed);
667        assert_eq!(env.get_color("c2").unwrap(), (50, 50, 50));
668        assert_eq!(env.set_color("c3", (50, 50, 50), &mut data).err().unwrap(), EnvErr::NotFound);
669        assert_eq!(env.set_color("s1", (50, 50, 50), &mut data).err().unwrap(), EnvErr::DifferentType);
670        assert_eq!(env.get("c1").unwrap(), EnvData::Color(20, 40, 60));
671        env.reset("c1", &mut data).unwrap();
672        assert_eq!(env.get_color("c1").unwrap(), (31, 33, 37));
673        assert_eq!(env.get_help("c1").unwrap(), "First Color");
674    }
675}