use crate::{ opt::{ActiveOpt, OptKind}, Command, }; use std::env; pub struct Context { opts: Vec, cmd: Command, pub(crate) env_prefix: Option, pub(crate) env_enabled: bool, } impl Context { pub(crate) fn new(cmd: Command, opts: Vec) -> Self { Self { opts, cmd, env_prefix: None, env_enabled: true, } } /// Checks for the existance of a flag pub fn flag(&self, name: &str) -> bool { self.opts .iter() .any(|o| o.definition.name == name && matches!(o.definition.kind, OptKind::Flag)) || self.get_env_value(name).is_some() } fn get_env_value(&self, name: &str) -> Option { if self.env_enabled == false { return None; } let name = self .env_prefix .as_ref() .map(|pre| format!("{}_{}", pre, name)) .unwrap_or(name.to_string()); env::var(name).ok() } /// Returns the value of an option if one exists pub fn get_value(&self, name: &str) -> Option { self.opts .iter() .find_map(|o| { if o.definition.name == name { Some(o.raw_value.first().cloned()) } else { None } }) .flatten() .or(self.get_env_value(name)) } /// Can be used to display the automatic help message for the current command. pub fn display_help(&self) { crate::command::print_command_help(&self.cmd, &vec![]) } } #[cfg(test)] mod tests { use crate::{App, Opt}; #[test] fn test_env() { std::env::set_var("thing", "1"); App::new() .opt(Opt::flag("thing").short("-t").long("--t")) .handler(|_, ctx, _| { assert_eq!(ctx.flag("thing"), true); }) .run_with(vec![]) .unwrap(); std::env::set_var("thing", "one"); App::new() .opt(Opt::scalar("thing").short("-t").long("--t")) .handler(|_, ctx, _| { assert_eq!(ctx.get_value("thing"), Some("one".into())); }) .run_with(vec![]) .unwrap(); std::env::set_var("thing", "one"); App::new() .opt(Opt::scalar("thing").short("t").long("thing")) .handler(|_, ctx, _| { assert_eq!(ctx.get_value("thing"), Some("1".into())); }) .run_with(vec!["-t".into(), "1".into()]) .unwrap(); } }