Matches is now a Type Alias, rather than its own struct

Since the original Matches structure was nothing more than a wrapper around a HashMap<String,
String>, the code has been updated to simply be a type alias to that type. Makes things easier.
This commit is contained in:
Zach Dziura 2015-06-23 03:31:02 +00:00
parent 632850c58c
commit 3c9dae504b
2 changed files with 47 additions and 33 deletions

View file

@ -21,19 +21,15 @@ use std::collections::hash_map::Keys;
use errors::{Error, ErrorKind}; use errors::{Error, ErrorKind};
use vars::Vars; use vars::Vars;
pub struct Matches { pub type Matches = HashMap<String, String>;
matches: HashMap<String, String>
}
pub fn matches(vars: &mut Vars, env_args: &[String]) -> Result<Matches, Error> { pub fn matches(vars: &mut Vars, env_args: &[String]) -> Result<Matches, Error> {
let mut matches: HashMap<String, String> = HashMap::new(); let mut matches: Matches = HashMap::new();
let mut args = env_args.iter(); let mut args = env_args.iter();
args.next(); // Remove the program name args.next(); // Remove the program name
let mut next_arg = args.next(); while let Some(mut current_arg) = args.next() {
while next_arg.is_some() {
let mut current_arg = next_arg.unwrap();
let mut arg_vec: Vec<String> = Vec::new(); let mut arg_vec: Vec<String> = Vec::new();
// Determine if current opt is in short, long, or arg form // Determine if current opt is in short, long, or arg form
@ -72,28 +68,34 @@ pub fn matches(vars: &mut Vars, env_args: &[String]) -> Result<Matches, Error> {
let arg = vars.get_arg().unwrap(); let arg = vars.get_arg().unwrap();
matches.insert(arg.name(), current_arg.clone()); matches.insert(arg.name(), current_arg.clone());
} }
next_arg = args.next();
} }
match vars.arg_len() { match vars.arg_len() {
0 => Ok(Matches { matches: matches }), 0 => Ok( matches ),
_ => Err(Error::new(ErrorKind::MissingArgument, vars.get_arg().unwrap().name())), _ => Err(Error::new(ErrorKind::MissingArgument, vars.get_arg().unwrap().name())),
} }
} }
impl Matches { trait MatchesTrait {
pub fn get(&self, arg: &str) -> Option<&String> { fn get(&self, arg: &str) -> Option<&String>;
self.matches.get(arg)
fn has_match(&self, arg: &str) -> bool;
fn matches(&self) -> Keys<String, String>;
}
impl MatchesTrait for Matches {
fn get(&self, arg: &str) -> Option<&String> {
self.get(arg)
} }
pub fn has_match(&self, arg: &str) -> bool { fn has_match(&self, arg: &str) -> bool {
let arg = String::from(arg); let arg = String::from(arg);
self.matches.contains_key(&arg) self.contains_key(&arg)
} }
pub fn matches(&self) -> Keys<String, String> { fn matches(&self) -> Keys<String, String> {
self.matches.keys() self.keys()
} }
} }

View file

@ -22,17 +22,18 @@ use errors::Error;
use token::{Token, token}; use token::{Token, token};
pub struct Vars { pub struct Vars {
opts: HashMap<String, Token>, tokens: Vec<Token>,
args: VecDeque<Token>, opts: HashMap<String, usize>,
pub tokens: Vec<Token>, args: VecDeque<usize>,
pub program_name: String pub program_name: String
} }
pub fn vars(program_name: &str, options: &[&str]) -> Result<Vars, Error> { pub fn vars(program_name: &str, options: &[&str]) -> Result<Vars, Error> {
let mut opts: HashMap<String, Token> = HashMap::new();
let mut args: VecDeque<Token> = VecDeque::new();
let mut tokens: Vec<Token> = Vec::new(); let mut tokens: Vec<Token> = Vec::new();
let mut opts: HashMap<String, usize> = HashMap::new();
let mut args: VecDeque<usize> = VecDeque::new();
let mut longest_token_len: usize = 0; let mut longest_token_len: usize = 0;
let mut index: usize = 0;
for opt in options.iter() { for opt in options.iter() {
let token = match token(opt) { let token = match token(opt) {
@ -42,18 +43,19 @@ pub fn vars(program_name: &str, options: &[&str]) -> Result<Vars, Error> {
if !token.is_group { if !token.is_group {
if token.is_arg { if token.is_arg {
args.push_back(token.clone()); args.push_back(index);
} else { } else {
if !token.short_name.is_empty() { if !token.short_name.is_empty() {
opts.insert(token.short_name.clone(), token.clone()); opts.insert(token.short_name.clone(), index);
} }
if !token.long_name.is_empty() { if !token.long_name.is_empty() {
opts.insert(token.long_name.clone(), token.clone()); opts.insert(token.long_name.clone(), index);
} }
} }
let token_len = token.len(); let token_len = token.len();
println!("Token {} length: {}", token.name(), token_len);
if token_len > 0 { if token_len > 0 {
if token_len > longest_token_len { if token_len > longest_token_len {
longest_token_len = token_len; longest_token_len = token_len;
@ -65,6 +67,7 @@ pub fn vars(program_name: &str, options: &[&str]) -> Result<Vars, Error> {
} }
} }
tokens.push(token); tokens.push(token);
index += 1;
} }
let help_token = Token { let help_token = Token {
@ -76,9 +79,10 @@ pub fn vars(program_name: &str, options: &[&str]) -> Result<Vars, Error> {
is_group: false, is_group: false,
padding: 0 padding: 0
}; };
opts.insert(String::from("-h"), help_token.clone()); tokens.push(help_token);
opts.insert(String::from("--help"), help_token.clone()); opts.insert(String::from("-h"), index);
opts.insert(String::from("--help"), index);
Ok(Vars { Ok(Vars {
opts: opts, opts: opts,
@ -89,16 +93,24 @@ pub fn vars(program_name: &str, options: &[&str]) -> Result<Vars, Error> {
} }
impl Vars { impl Vars {
pub fn get_opt(&self, opt_name: &String) -> Option<&Token> { pub fn get_opt(&self, opt_name: &str) -> Option<&Token> {
self.opts.get(opt_name) if let Some(&index) = self.opts.get(opt_name) {
self.tokens.get(index)
} else {
None
}
} }
pub fn contains_opt(&self, opt: &String) -> bool { pub fn contains_opt(&self, opt: &str) -> bool {
self.opts.contains_key(opt) self.opts.contains_key(opt)
} }
pub fn get_arg(&mut self) -> Option<Token> { pub fn get_arg(&mut self) -> Option<&Token> {
self.args.pop_front() if let Some(index) = self.args.pop_front() {
self.tokens.get(index)
} else {
None
}
} }
pub fn arg_len(&self) -> usize { pub fn arg_len(&self) -> usize {