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
use crate::{Flag, FlagValue}; pub struct Context { pub args: Vec<String>, flags: Option<Vec<(String, Option<FlagValue>)>> } impl Context { pub fn new(args: Vec<String>, flags: Option<Vec<Flag>>) -> Self { let mut v = Vec::new(); let flags_val = match flags { Some(flags) => { for flag in flags { v.push((flag.name.to_string(), flag.value(args.clone()))) } Some(v) } None => None }; Self { args, flags: flags_val } } fn option_flag_value(&self, name: &str) -> Option<&FlagValue> { self.flags.as_ref() .and_then(|flags| flags.into_iter().find(|flag| flag.0 == name.to_string())) .and_then(|flag| flag.1.as_ref()) } pub fn bool_flag(&self, name: &str) -> bool { match self.option_flag_value(name) { Some(FlagValue::Bool(val)) => { (*val).clone() }, _ => false } } pub fn string_flag(&self, name: &str) -> Option<String> { match self.option_flag_value(name) { Some(FlagValue::String(val)) => Some((&val).to_string()), _ => None } } pub fn int_flag(&self, name: &str) -> Option<isize> { match self.option_flag_value(name) { Some(FlagValue::Int(val)) => Some(val.clone()), _ => None } } pub fn float_flag(&self, name: &str) -> Option<f64> { match self.option_flag_value(name) { Some(FlagValue::Float(val)) => Some(val.clone()), _ => None } } } #[cfg(test)] mod tests { use crate::{Context, Flag, FlagType}; #[test] fn context_test() { let args = vec![ "cli".to_string(), "command".to_string(), "args".to_string(), "--bool".to_string(), "--string".to_string(), "test".to_string(), "--int".to_string(), "100".to_string(), "--float".to_string(), "1.23".to_string(), ]; let flags = vec![ Flag::new("bool", "", FlagType::Bool), Flag::new("string", "", FlagType::String), Flag::new("int", "", FlagType::Int), Flag::new("float", "", FlagType::Float) ]; let context = Context::new(args, Some(flags)); assert_eq!(true, context.bool_flag("bool")); match context.string_flag("string") { Some(val) => assert_eq!("test".to_string(), val), _ => assert!(false) } match context.int_flag("int") { Some(val) => assert_eq!(100, val), _ => assert!(false) } match context.float_flag("float") { Some(val) => assert_eq!(1.23, val), _ => assert!(false) } } }