use crate::{CommandSummary, FlagSummary, ParamSummary, ResourceSummary}; /// Intent structure which represents user intent. #[derive(Debug, Clone, PartialEq)] pub struct Intent { args: Vec, command: CommandSummary, supcommands: Vec, subcommands: Vec, flags: Vec, params: Vec, resources: Vec, } /// Intent structure implementation. impl Intent { /// Returns new instance. pub fn new( args: Vec, command: CommandSummary, supcommands: Vec, subcommands: Vec, flags: Vec, params: Vec, resources: Vec, ) -> Self { Self { args, command, supcommands, subcommands, flags, params, resources } } /// Returns raw command-line arguments. pub fn args(&self) -> &Vec { &self.args } /// Returns summary objects of the executed command. pub fn command(&self) -> &CommandSummary { &self.command } /// Returns summary objects of parent commands in a tree. pub fn supcommands(&self) -> &Vec { &self.supcommands } /// Returns summary objects of child commands. pub fn subcommands(&self) -> &Vec{ &self.subcommands } /// Returns summary objects of all flags. pub fn flags(&self) -> &Vec { &self.flags } /// Returns summary objects of a specific flag. pub fn flag>(&self, name: S) -> Option<&FlagSummary> { let name = name.into(); self.flags.iter().find(|f| *f.name() == name) } /// Returns summary objects of all params. pub fn params(&self) -> &Vec { &self.params } /// Returns summary objects of a specific flag. pub fn param>(&self, name: S) -> Option<&ParamSummary> { let name = name.into(); self.params.iter().find(|f| *f.name() == name) } /// Returns summary objects of all resources. pub fn resources(&self) -> &Vec { &self.resources } /// Returns summary objects of a specific resource. pub fn resource>(&self, name: S) -> Option<&ResourceSummary> { let name = name.into(); self.resources.iter().find(|f| *f.name() == name) } /// Returns true if command-line arguments are present. pub fn has_args(&self) -> bool { !self.args.is_empty() } /// Returns true if command-line argument is present. pub fn has_arg>(&self, name: S) -> bool { let name = name.into(); self.args.iter().any(|a| *a == name) } /// Returns true if the executed command has parent commands. pub fn has_supcommands(&self) -> bool { !self.supcommands.is_empty() } /// Returns true if the executed command has child commands. pub fn has_subcommands(&self) -> bool { !self.subcommands.is_empty() } /// Returns true if the executed command has flags. pub fn has_flags(&self) -> bool { !self.flags.is_empty() } /// Returns true if flag is present. pub fn has_flag>(&self, name: S) -> bool { self.flag(name.into()).is_some() } /// Returns true if flag is present. pub fn has_provided_flag>(&self, name: S) -> bool { let name = name.into(); match self.flag(name) { Some(f) => f.provided(), None => false, } } /// Returns true if the executed command has params. pub fn has_params(&self) -> bool { !self.params.is_empty() } /// Returns true if param is present. pub fn has_param>(&self, name: S) -> bool { self.param(name.into()).is_some() } /// Returns true if param is present. pub fn has_provided_param>(&self, name: S) -> bool { let name = name.into(); match self.param(name) { Some(f) => f.provided(), None => false, } } /// Returns true if the executed command has resources. pub fn has_resources(&self) -> bool { !self.resources.is_empty() } /// Returns true if resource is present. pub fn has_resource>(&self, name: S) -> bool { self.resource(name.into()).is_some() } } #[cfg(test)] mod tests { use super::*; fn intent_with_args(args: Vec) -> Intent { let command: CommandSummary = CommandSummary::with_name("", None, None, None, None); let supcommands: Vec = vec![]; let subcommands: Vec = vec![]; let flags: Vec = vec![]; let params: Vec = vec![]; let resources: Vec = vec![]; Intent::new(args, command, supcommands, subcommands, flags, params, resources) } fn intent_with_flags(flags: Vec) -> Intent { let args: Vec = vec![]; let command: CommandSummary = CommandSummary::with_name("", None, None, None, None); let supcommands: Vec = vec![]; let subcommands: Vec = vec![]; let flags: Vec = flags; let params: Vec = vec![]; let resources: Vec = vec![]; Intent::new(args, command, supcommands, subcommands, flags, params, resources) } fn intent_with_params(params: Vec) -> Intent { let args: Vec = vec![]; let command: CommandSummary = CommandSummary::with_name("", None, None, None, None); let supcommands: Vec = vec![]; let subcommands: Vec = vec![]; let flags: Vec = vec![]; let params: Vec = params; let resources: Vec = vec![]; Intent::new(args, command, supcommands, subcommands, flags, params, resources) } #[test] fn provides_flag_by_name() { let intent = intent_with_flags(vec![ FlagSummary::with_name("a", None, None, None, None, false, false), FlagSummary::with_name("b", None, None, None, None, false, false), ]); assert_eq!(intent.flag("b").unwrap().name(), "b"); } #[test] fn provides_param_by_name() { let intent = intent_with_params(vec![ ParamSummary::with_name("a", None, None, None, false), ParamSummary::with_name("b", None, None, None, false), ]); assert_eq!(intent.param("b").unwrap().name(), "b"); } #[test] fn checks_argument_existance() { let intent = intent_with_args(vec![ "--b".to_string(), "-c".to_string(), ]); assert_eq!(intent.has_arg("-c"), true); assert_eq!(intent.has_arg("b"), false); } #[test] fn checks_flag_existance() { let intent = intent_with_flags(vec![ FlagSummary::with_name("b", None, None, None, None, false, false), ]); assert_eq!(intent.has_flag("b"), true); assert_eq!(intent.has_flag("x"), false); } #[test] fn checks_param_existance() { let intent = intent_with_params(vec![ ParamSummary::with_name("b", None, None, None, false), ]); assert_eq!(intent.has_param("b"), true); assert_eq!(intent.has_param("x"), false); } }