pub mod parsers;
use std::collections::HashMap;
use std::fmt;
#[derive(Debug)]
pub struct Command {
pub argv: Vec<String>,
pub argc: usize,
pub executable: String,
pub options: Vec<String>,
pub definitions: HashMap<String, String>,
}
impl fmt::Display for Command {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut commandstring = String::new();
for substring in &self.argv {
commandstring.push_str(&substring[..]);
commandstring.push_str(" ");
}
write!(f, "Command: '{}'", &commandstring[..].trim_right())
}
}
impl Command {
pub fn new(arguments: Vec<String>) -> Self {
let arguments_definition = arguments.clone();
let executable_definition = &arguments[0];
let size_definition = arguments.len();
let vec_options = parsers::parse_options(&arguments);
let definitions_hm = parsers::parse_definitions(&arguments);
Command {
argv: arguments_definition,
argc: size_definition,
executable: executable_definition.to_string(),
options: vec_options,
definitions: definitions_hm,
}
}
pub fn has_args(&self) -> bool {
self.argv[1..].len() > 0
}
pub fn has_definitions(&self) -> bool {
self.definitions.len() > 0
}
pub fn has_options(&self) -> bool {
self.options.len() > 0
}
pub fn contains_arg(&self, needle: &str) -> bool {
self.argv[1..].contains(&String::from(needle))
}
pub fn contains_definition(&self, needle: &str) -> bool {
match self.definitions.get(&String::from(needle)) {
Some(_) => true,
None => false,
}
}
pub fn contains_option(&self, needle: &str) -> bool {
self.options.contains(&String::from(needle))
}
pub fn get_definition_for(&self, needle: &str) -> Option<&String> {
self.definitions.get(&String::from(needle))
}
pub fn get_argument_after(&self, needle: &str) -> Option<&String> {
for (index, value) in self.argv.iter().enumerate() {
if value == needle {
return self.argv.get(index + 1);
}
}
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn command_instantiation_argv_field() {
let c = Command::new(vec!["test".to_string(), "--help".to_string()]);
assert!(c.argv == vec!["test".to_string(), "--help".to_string()]);
}
#[test]
fn command_instantiation_argc_field_one_arg() {
let c = Command::new(vec!["test".to_string()]);
assert!(c.argc == 1);
}
#[test]
fn command_instantiation_argc_field_two_args() {
let c = Command::new(vec!["test".to_string(), "--help".to_string()]);
assert!(c.argc == 2);
}
#[test]
fn command_instantiation_executable_field() {
let c = Command::new(vec!["test".to_string(), "--help".to_string()]);
assert!(c.executable == "test".to_string());
}
#[test]
fn command_instantiation_definitions_field_single_def() {
let c = Command::new(vec![
"test".to_string(),
"--something".to_string(),
"--option=define".to_string(),
]);
let mut expected_hm: HashMap<String, String> = HashMap::new();
expected_hm.insert("--option".to_string(), "define".to_string());
assert_eq!(c.definitions, expected_hm);
}
#[test]
fn command_instantiation_definitions_field_multi_def() {
let c = Command::new(vec![
"test".to_string(),
"--something".to_string(),
"--option=define".to_string(),
"--another=otherdef".to_string(),
"--".to_string(),
"--absent=true".to_string(),
]);
let mut expected_hm: HashMap<String, String> = HashMap::new();
expected_hm.insert("--option".to_string(), "define".to_string());
expected_hm.insert("--another".to_string(), "otherdef".to_string());
assert_eq!(c.definitions, expected_hm);
}
#[test]
fn command_method_has_args_true() {
let c = Command::new(vec!["test".to_string(), "--help".to_string()]);
assert_eq!(c.has_args(), true);
let c = Command::new(vec!["test".to_string(), "subcmd".to_string()]);
assert_eq!(c.has_args(), true);
}
#[test]
fn command_method_has_args_false() {
let c = Command::new(vec!["test".to_string()]); assert_eq!(c.has_args(), false);
}
#[test]
fn command_method_has_definitions_true() {
let c = Command::new(vec!["test".to_string(), "--opt=def".to_string()]);
assert_eq!(c.has_definitions(), true);
let c = Command::new(vec!["test".to_string(), "-o=d".to_string()]);
assert_eq!(c.has_definitions(), true);
}
#[test]
fn command_method_has_definitions_false() {
let c = Command::new(vec!["test".to_string()]); assert_eq!(c.has_definitions(), false);
}
#[test]
fn command_method_has_options_true() {
let c = Command::new(vec!["test".to_string(), "--help".to_string()]);
assert!(c.has_options() == true);
}
#[test]
fn command_method_has_options_false() {
let c = Command::new(vec!["test".to_string(), "subcmd".to_string()]);
assert!(c.has_options() == false);
}
#[test]
fn command_method_contains_arg() {
let c = Command::new(vec![
"test".to_string(),
"subcmd".to_string(),
"--help".to_string(),
]);
assert_eq!(c.contains_arg("subcmd"), true);
assert_eq!(c.contains_arg("--help"), true);
assert_eq!(c.contains_arg("bogus"), false);
assert_eq!(c.contains_arg("test"), false); }
#[test]
fn command_method_contains_definition() {
let c = Command::new(vec![
"test".to_string(),
"subcmd".to_string(),
"--help".to_string(),
"--option=definition".to_string(),
"--another=deftwo".to_string(),
]);
assert_eq!(c.contains_definition("--option"), true);
assert_eq!(c.contains_definition("--another"), true);
assert_eq!(c.contains_definition("--bogus"), false);
assert_eq!(c.contains_definition("--help"), false);
}
#[test]
fn command_method_contains_option() {
let c = Command::new(vec![
"test".to_string(),
"subcmd".to_string(),
"--help".to_string(),
]);
assert_eq!(c.contains_option("--help"), true);
assert_eq!(c.contains_option("--bogus"), false);
assert_eq!(c.contains_option("help"), false); }
#[test]
fn command_method_get_definition_for_def_present() {
let c = Command::new(vec![
"test".to_string(),
"subcmd".to_string(),
"--help".to_string(),
"--option=definition".to_string(),
]);
assert_eq!(
c.get_definition_for("--option"),
Some(&String::from("definition"))
);
}
#[test]
fn command_method_get_definition_for_def_absent() {
let c = Command::new(vec![
"test".to_string(),
"subcmd".to_string(),
"--help".to_string(),
]);
assert_eq!(c.get_definition_for("--option"), None);
}
#[test]
fn command_method_get_argument_after_arg_present() {
let c = Command::new(vec![
"test".to_string(),
"-o".to_string(),
"path".to_string(),
]);
assert_eq!(c.get_argument_after("-o"), Some(&String::from("path")));
}
#[test]
fn command_method_get_argument_after_arg_absent() {
let c = Command::new(vec!["test".to_string(), "-o".to_string()]);
assert_eq!(c.get_argument_after("-o"), None);
}
}