mirror of
https://github.com/Llewellynvdm/exa.git
synced 2024-12-28 10:40:48 +00:00
Search for long options through matches
Casualty here was that you can’t have static values reference one another directly, so the static args slice had to be turned into a slice *of references* rather than of values. No big deal, just have to write & a few more times.
This commit is contained in:
parent
e08d7fe524
commit
53dc370a41
@ -13,6 +13,15 @@ pub enum Flag {
|
|||||||
Long(LongArg),
|
Long(LongArg),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Flag {
|
||||||
|
fn matches(&self, arg: &Arg) -> bool {
|
||||||
|
match *self {
|
||||||
|
Flag::Short(short) => arg.short == Some(short),
|
||||||
|
Flag::Long(long) => arg.long == long,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum Strictness {
|
pub enum Strictness {
|
||||||
ComplainAboutRedundantArguments,
|
ComplainAboutRedundantArguments,
|
||||||
@ -33,7 +42,7 @@ pub struct Arg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct Args(&'static [Arg]);
|
pub struct Args(&'static [&'static Arg]);
|
||||||
|
|
||||||
impl Args {
|
impl Args {
|
||||||
fn lookup_short<'a>(&self, short: ShortArg) -> Result<&Arg, ParseError<'a>> {
|
fn lookup_short<'a>(&self, short: ShortArg) -> Result<&Arg, ParseError<'a>> {
|
||||||
@ -60,6 +69,20 @@ pub struct Matches<'a> {
|
|||||||
frees: Vec<&'a OsStr>,
|
frees: Vec<&'a OsStr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Matches<'a> {
|
||||||
|
fn has(&self, arg: &Arg) -> bool {
|
||||||
|
self.flags.iter().rev()
|
||||||
|
.find(|tuple| tuple.1.is_none() && tuple.0.matches(arg))
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self, arg: &Arg) -> Option<&OsStr> {
|
||||||
|
self.flags.iter().rev()
|
||||||
|
.find(|tuple| tuple.1.is_some() && tuple.0.matches(arg))
|
||||||
|
.map(|tuple| tuple.1.unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum ParseError<'a> {
|
pub enum ParseError<'a> {
|
||||||
NeedsValue { flag: Flag },
|
NeedsValue { flag: Flag },
|
||||||
@ -233,7 +256,7 @@ mod split_test {
|
|||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod parse_test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
macro_rules! test {
|
macro_rules! test {
|
||||||
@ -247,10 +270,10 @@ mod test {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static TEST_ARGS: &'static [Arg] = &[
|
static TEST_ARGS: &[&Arg] = &[
|
||||||
Arg { short: Some(b'l'), long: "long", takes_value: TakesValue::Forbidden },
|
&Arg { short: Some(b'l'), long: "long", takes_value: TakesValue::Forbidden },
|
||||||
Arg { short: Some(b'v'), long: "verbose", takes_value: TakesValue::Forbidden },
|
&Arg { short: Some(b'v'), long: "verbose", takes_value: TakesValue::Forbidden },
|
||||||
Arg { short: Some(b'c'), long: "count", takes_value: TakesValue::Necessary }
|
&Arg { short: Some(b'c'), long: "count", takes_value: TakesValue::Necessary }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
@ -302,3 +325,81 @@ mod test {
|
|||||||
test!(unknown_short_eq: [os("-q=shhh")] => Err(ParseError::UnknownShortArgument { attempt: b'q' }));
|
test!(unknown_short_eq: [os("-q=shhh")] => Err(ParseError::UnknownShortArgument { attempt: b'q' }));
|
||||||
test!(unknown_short_2nd_eq: [os("-lq=shhh")] => Err(ParseError::UnknownShortArgument { attempt: b'q' }));
|
test!(unknown_short_2nd_eq: [os("-lq=shhh")] => Err(ParseError::UnknownShortArgument { attempt: b'q' }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod matches_test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
static LONG: Arg = Arg { short: Some(b'l'), long: "long", takes_value: TakesValue::Forbidden };
|
||||||
|
static VERBOSE: Arg = Arg { short: Some(b'v'), long: "verbose", takes_value: TakesValue::Forbidden };
|
||||||
|
static COUNT: Arg = Arg { short: Some(b'c'), long: "count", takes_value: TakesValue::Necessary };
|
||||||
|
static TEST_ARGS: &[&Arg] = &[ &LONG, &VERBOSE, &COUNT ];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn has_long() {
|
||||||
|
let matches = Matches {
|
||||||
|
frees: Vec::new(),
|
||||||
|
flags: vec![ (Flag::Short(b'l'), None) ],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(matches.has(&LONG));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn has_long_twice() {
|
||||||
|
let matches = Matches {
|
||||||
|
frees: Vec::new(),
|
||||||
|
flags: vec![ (Flag::Short(b'l'), None),
|
||||||
|
(Flag::Short(b'l'), None) ],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(matches.has(&LONG));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_long() {
|
||||||
|
let matches = Matches {
|
||||||
|
frees: Vec::new(),
|
||||||
|
flags: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(!matches.has(&LONG));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn only_count() {
|
||||||
|
let everything = os("everything");
|
||||||
|
|
||||||
|
let matches = Matches {
|
||||||
|
frees: Vec::new(),
|
||||||
|
flags: vec![ (Flag::Short(b'c'), Some(&*everything)) ],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(matches.get(&COUNT), Some(&*everything));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rightmost_count() {
|
||||||
|
let everything = os("everything");
|
||||||
|
let nothing = os("nothing");
|
||||||
|
|
||||||
|
let matches = Matches {
|
||||||
|
frees: Vec::new(),
|
||||||
|
flags: vec![ (Flag::Short(b'c'), Some(&*everything)),
|
||||||
|
(Flag::Short(b'c'), Some(&*nothing)) ],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(matches.get(&COUNT), Some(&*nothing));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_count() {
|
||||||
|
let matches = Matches {
|
||||||
|
frees: Vec::new(),
|
||||||
|
flags: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(!matches.has(&COUNT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user