Separate the matched flags from the free strings

Originally, both the matched flags and the list of free strings were returned from the parsing function and then passed around to every type that had a ‘deduce’ method. This worked, but the list of free strings was carried around with it, never used.

Now, only the flags are passed around. They’re in a new struct which has the methods the Matches had.

Both of Matches’s fields are now just data, and all of the methods on MatchedFlags don’t ignore any fields, so it’s more cohesive, at least I think that’s the word.

Building up the MatchedFlags is a bit more annoying though because the vector is now hidden behind a field.
This commit is contained in:
Benjamin Sago 2017-08-05 19:11:00 +01:00
parent 0456e7cfbd
commit 9872eba821
6 changed files with 131 additions and 94 deletions

View File

@ -1,4 +1,4 @@
use options::parser::Matches;
use options::parser::MatchedFlags;
use options::{flags, Misfire};
use fs::dir_action::{DirAction, RecurseOptions};
@ -7,7 +7,7 @@ use fs::dir_action::{DirAction, RecurseOptions};
impl DirAction {
/// Determine which action to perform when trying to list a directory.
pub fn deduce(matches: &Matches) -> Result<DirAction, Misfire> {
pub fn deduce(matches: &MatchedFlags) -> Result<DirAction, Misfire> {
let recurse = matches.has(&flags::RECURSE);
let list = matches.has(&flags::LIST_DIRS);
let tree = matches.has(&flags::TREE);
@ -36,7 +36,7 @@ impl DirAction {
impl RecurseOptions {
/// Determine which files should be recursed into.
pub fn deduce(matches: &Matches, tree: bool) -> Result<RecurseOptions, Misfire> {
pub fn deduce(matches: &MatchedFlags, tree: bool) -> Result<RecurseOptions, Misfire> {
let max_depth = if let Some(level) = matches.get(&flags::LEVEL) {
match level.to_string_lossy().parse() {
Ok(l) => Some(l),
@ -75,7 +75,7 @@ mod test {
let bits = $inputs.as_ref().into_iter().map(|&o| os(o)).collect::<Vec<OsString>>();
let results = Args(TEST_ARGS).parse(bits.iter());
assert_eq!($type::deduce(results.as_ref().unwrap()), $result);
assert_eq!($type::deduce(&results.unwrap().flags), $result);
}
};
}

View File

@ -4,14 +4,14 @@ use fs::DotFilter;
use fs::filter::{FileFilter, SortField, SortCase, IgnorePatterns};
use options::{flags, Misfire};
use options::parser::Matches;
use options::parser::MatchedFlags;
impl FileFilter {
/// Determines the set of file filter options to use, based on the users
/// command-line arguments.
pub fn deduce(matches: &Matches) -> Result<FileFilter, Misfire> {
pub fn deduce(matches: &MatchedFlags) -> Result<FileFilter, Misfire> {
Ok(FileFilter {
list_dirs_first: matches.has(&flags::DIRS_FIRST),
reverse: matches.has(&flags::REVERSE),
@ -39,7 +39,7 @@ impl SortField {
/// Determine the sort field to use, based on the presence of a “sort”
/// argument. This will return `Err` if the option is there, but does not
/// correspond to a valid field.
fn deduce(matches: &Matches) -> Result<SortField, Misfire> {
fn deduce(matches: &MatchedFlags) -> Result<SortField, Misfire> {
let word = match matches.get(&flags::SORT) {
Some(w) => w,
None => return Ok(SortField::default()),
@ -86,7 +86,7 @@ impl SortField {
impl DotFilter {
pub fn deduce(matches: &Matches) -> Result<DotFilter, Misfire> {
pub fn deduce(matches: &MatchedFlags) -> Result<DotFilter, Misfire> {
match matches.count(&flags::ALL) {
0 => Ok(DotFilter::JustFiles),
1 => Ok(DotFilter::Dotfiles),
@ -101,7 +101,7 @@ impl IgnorePatterns {
/// Determines the set of file filter options to use, based on the users
/// command-line arguments.
pub fn deduce(matches: &Matches) -> Result<IgnorePatterns, Misfire> {
pub fn deduce(matches: &MatchedFlags) -> Result<IgnorePatterns, Misfire> {
let patterns = match matches.get(&flags::IGNORE_GLOB) {
None => Ok(Vec::new()),
Some(is) => is.to_string_lossy().split('|').map(|a| glob::Pattern::new(a)).collect(),
@ -139,7 +139,7 @@ mod test {
let bits = $inputs.as_ref().into_iter().map(|&o| os(o)).collect::<Vec<OsString>>();
let results = Args(TEST_ARGS).parse(bits.iter());
assert_eq!($type::deduce(results.as_ref().unwrap()), $result);
assert_eq!($type::deduce(&results.unwrap().flags), $result);
}
};
}

View File

@ -1,7 +1,7 @@
use std::fmt;
use options::flags;
use options::parser::Matches;
use options::parser::MatchedFlags;
use fs::feature::xattr;
@ -72,7 +72,7 @@ impl HelpString {
/// Determines how to show help, if at all, based on the users
/// command-line arguments. This one works backwards from the other
/// deduce functions, returning Err if help needs to be shown.
pub fn deduce(matches: &Matches) -> Result<(), HelpString> {
pub fn deduce(matches: &MatchedFlags) -> Result<(), HelpString> {
if matches.has(&flags::HELP) {
let only_long = matches.has(&flags::LONG);
let git = cfg!(feature="git");

View File

@ -88,7 +88,7 @@ pub use self::misfire::Misfire;
mod parser;
mod flags;
use self::parser::Matches;
use self::parser::MatchedFlags;
/// These **options** represent a parsed, error-checked versions of the
@ -113,20 +113,21 @@ impl Options {
#[allow(unused_results)]
pub fn getopts<'args, I>(args: I) -> Result<(Options, Vec<&'args OsStr>), Misfire>
where I: IntoIterator<Item=&'args OsString> {
use options::parser::Matches;
let matches = match flags::ALL_ARGS.parse(args) {
let Matches { flags, frees } = match flags::ALL_ARGS.parse(args) {
Ok(m) => m,
Err(e) => return Err(Misfire::InvalidOptions(e)),
};
HelpString::deduce(&matches).map_err(Misfire::Help)?;
HelpString::deduce(&flags).map_err(Misfire::Help)?;
if matches.has(&flags::VERSION) {
if flags.has(&flags::VERSION) {
return Err(Misfire::Version);
}
let options = Options::deduce(&matches)?;
Ok((options, matches.frees))
let options = Options::deduce(&flags)?;
Ok((options, frees))
}
/// Whether the View specified in this set of options includes a Git
@ -142,7 +143,7 @@ impl Options {
/// Determines the complete set of options based on the given command-line
/// arguments, after theyve been parsed.
fn deduce(matches: &Matches) -> Result<Options, Misfire> {
fn deduce(matches: &MatchedFlags) -> Result<Options, Misfire> {
let dir_action = DirAction::deduce(matches)?;
let filter = FileFilter::deduce(matches)?;
let view = View::deduce(matches)?;

View File

@ -130,7 +130,7 @@ impl Args {
// The results that get built up.
let mut results = Matches {
flags: Vec::new(),
flags: MatchedFlags { flags: Vec::new() },
frees: Vec::new(),
};
@ -163,7 +163,7 @@ impl Args {
let arg = self.lookup_long(before)?;
let flag = Flag::Long(arg.long);
match arg.takes_value {
Necessary => results.flags.push((flag, Some(after))),
Necessary => results.flags.flags.push((flag, Some(after))),
Forbidden => return Err(ParseError::ForbiddenValue { flag })
}
}
@ -174,10 +174,10 @@ impl Args {
let arg = self.lookup_long(long_arg_name)?;
let flag = Flag::Long(arg.long);
match arg.takes_value {
Forbidden => results.flags.push((flag, None)),
Forbidden => results.flags.flags.push((flag, None)),
Necessary => {
if let Some(next_arg) = inputs.next() {
results.flags.push((flag, Some(next_arg)));
results.flags.flags.push((flag, Some(next_arg)));
}
else {
return Err(ParseError::NeedsValue { flag })
@ -212,7 +212,7 @@ impl Args {
let arg = self.lookup_short(*byte)?;
let flag = Flag::Short(*byte);
match arg.takes_value {
Forbidden => results.flags.push((flag, None)),
Forbidden => results.flags.flags.push((flag, None)),
Necessary => return Err(ParseError::NeedsValue { flag })
}
}
@ -221,7 +221,7 @@ impl Args {
let arg = self.lookup_short(*arg_with_value)?;
let flag = Flag::Short(arg.short.unwrap());
match arg.takes_value {
Necessary => results.flags.push((flag, Some(after))),
Necessary => results.flags.flags.push((flag, Some(after))),
Forbidden => return Err(ParseError::ForbiddenValue { flag })
}
}
@ -243,15 +243,15 @@ impl Args {
let arg = self.lookup_short(*byte)?;
let flag = Flag::Short(*byte);
match arg.takes_value {
Forbidden => results.flags.push((flag, None)),
Forbidden => results.flags.flags.push((flag, None)),
Necessary => {
if index < bytes.len() - 1 {
let remnants = &bytes[index+1 ..];
results.flags.push((flag, Some(OsStr::from_bytes(remnants))));
results.flags.flags.push((flag, Some(OsStr::from_bytes(remnants))));
break;
}
else if let Some(next_arg) = inputs.next() {
results.flags.push((flag, Some(next_arg)));
results.flags.flags.push((flag, Some(next_arg)));
}
else {
return Err(ParseError::NeedsValue { flag })
@ -287,20 +287,31 @@ impl Args {
}
/// The **matches** are the result of parsing
/// The **matches** are the result of parsing the users command-line strings.
#[derive(PartialEq, Debug)]
pub struct Matches<'args> {
/// The flags that were
/// Long and short arguments need to be kept in the same vector, because
/// we usually want the one nearest the end to count.
pub flags: Vec<(Flag, Option<&'args OsStr>)>,
/// The flags that were parsed from the users input.
pub flags: MatchedFlags<'args>,
/// The strings that werent matched as arguments.
/// All the strings that werent matched as arguments, as well as anything
/// after the special "--" string.
pub frees: Vec<&'args OsStr>,
}
impl<'a> Matches<'a> {
#[derive(PartialEq, Debug)]
pub struct MatchedFlags<'args> {
/// The individual flags from the users input, in the order they were
/// originally given.
///
/// Long and short arguments need to be kept in the same vector because
/// we usually want the one nearest the end to count, and to know this,
/// we need to know where they are in relation to one another.
flags: Vec<(Flag, Option<&'args OsStr>)>,
}
impl<'a> MatchedFlags<'a> {
/// Whether the given argument was specified.
pub fn has(&self, arg: &Arg) -> bool {
@ -424,12 +435,39 @@ mod parse_test {
use super::*;
macro_rules! test {
($name:ident: $inputs:expr => $result:expr) => {
($name:ident: $inputs:expr => frees: $frees:expr, flags: $flags:expr) => {
#[test]
fn $name() {
// Annoyingly the input &strs need to be converted to OsStrings
let inputs: Vec<OsString> = $inputs.as_ref().into_iter().map(|&o| os(o)).collect();
// Same with the frees
let frees: Vec<OsString> = $frees.as_ref().into_iter().map(|&o| os(o)).collect();
let frees: Vec<&OsStr> = frees.iter().map(|os| os.as_os_str()).collect();
// And again for the flags
let flags: Vec<(Flag, Option<&OsStr>)> = $flags
.as_ref()
.into_iter()
.map(|&(ref f, ref os): &(Flag, Option<&'static str>)| (f.clone(), os.map(OsStr::new)))
.collect();
let got = Args(TEST_ARGS).parse(inputs.iter());
let expected = Ok(Matches { frees, flags: MatchedFlags { flags } });
assert_eq!(got, expected);
}
};
($name:ident: $inputs:expr => error $error:expr) => {
#[test]
fn $name() {
use self::ParseError::*;
let bits = $inputs.as_ref().into_iter().map(|&o| os(o)).collect::<Vec<OsString>>();
let results = Args(TEST_ARGS).parse(bits.iter());
assert_eq!(results, $result);
let got = Args(TEST_ARGS).parse(bits.iter());
assert_eq!(got, Err($error));
}
};
}
@ -442,52 +480,52 @@ mod parse_test {
// Just filenames
test!(empty: [] => Ok(Matches { frees: vec![], flags: vec![] }));
test!(one_arg: ["exa"] => Ok(Matches { frees: vec![ &os("exa") ], flags: vec![] }));
test!(empty: [] => frees: [], flags: []);
test!(one_arg: ["exa"] => frees: [ "exa" ], flags: []);
// Dashes and double dashes
test!(one_dash: ["-"] => Ok(Matches { frees: vec![ &os("-") ], flags: vec![] }));
test!(two_dashes: ["--"] => Ok(Matches { frees: vec![], flags: vec![] }));
test!(two_file: ["--", "file"] => Ok(Matches { frees: vec![ &os("file") ], flags: vec![] }));
test!(two_arg_l: ["--", "--long"] => Ok(Matches { frees: vec![ &os("--long") ], flags: vec![] }));
test!(two_arg_s: ["--", "-l"] => Ok(Matches { frees: vec![ &os("-l") ], flags: vec![] }));
test!(one_dash: ["-"] => frees: [ "-" ], flags: []);
test!(two_dashes: ["--"] => frees: [], flags: []);
test!(two_file: ["--", "file"] => frees: [ "file" ], flags: []);
test!(two_arg_l: ["--", "--long"] => frees: [ "--long" ], flags: []);
test!(two_arg_s: ["--", "-l"] => frees: [ "-l" ], flags: []);
// Long args
test!(long: ["--long"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Long("long"), None) ] }));
test!(long_then: ["--long", "4"] => Ok(Matches { frees: vec![ &os("4") ], flags: vec![ (Flag::Long("long"), None) ] }));
test!(long_two: ["--long", "--verbose"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Long("long"), None), (Flag::Long("verbose"), None) ] }));
test!(long: ["--long"] => frees: [], flags: [ (Flag::Long("long"), None) ]);
test!(long_then: ["--long", "4"] => frees: [ "4" ], flags: [ (Flag::Long("long"), None) ]);
test!(long_two: ["--long", "--verbose"] => frees: [], flags: [ (Flag::Long("long"), None), (Flag::Long("verbose"), None) ]);
// Long args with values
test!(bad_equals: ["--long=equals"] => Err(ParseError::ForbiddenValue { flag: Flag::Long("long") }));
test!(no_arg: ["--count"] => Err(ParseError::NeedsValue { flag: Flag::Long("count") }));
test!(arg_equals: ["--count=4"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Long("count"), Some(&*os("4"))) ] }));
test!(arg_then: ["--count", "4"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Long("count"), Some(&*os("4"))) ] }));
test!(bad_equals: ["--long=equals"] => error ForbiddenValue { flag: Flag::Long("long") });
test!(no_arg: ["--count"] => error NeedsValue { flag: Flag::Long("count") });
test!(arg_equals: ["--count=4"] => frees: [], flags: [ (Flag::Long("count"), Some("4")) ]);
test!(arg_then: ["--count", "4"] => frees: [], flags: [ (Flag::Long("count"), Some("4")) ]);
// Short args
test!(short: ["-l"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Short(b'l'), None) ] }));
test!(short_then: ["-l", "4"] => Ok(Matches { frees: vec![ &*os("4") ], flags: vec![ (Flag::Short(b'l'), None) ] }));
test!(short_two: ["-lv"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Short(b'l'), None), (Flag::Short(b'v'), None) ] }));
test!(mixed: ["-v", "--long"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Short(b'v'), None), (Flag::Long("long"), None) ] }));
test!(short: ["-l"] => frees: [], flags: [ (Flag::Short(b'l'), None) ]);
test!(short_then: ["-l", "4"] => frees: [ "4" ], flags: [ (Flag::Short(b'l'), None) ]);
test!(short_two: ["-lv"] => frees: [], flags: [ (Flag::Short(b'l'), None), (Flag::Short(b'v'), None) ]);
test!(mixed: ["-v", "--long"] => frees: [], flags: [ (Flag::Short(b'v'), None), (Flag::Long("long"), None) ]);
// Short args with values
test!(bad_short: ["-l=equals"] => Err(ParseError::ForbiddenValue { flag: Flag::Short(b'l') }));
test!(short_none: ["-c"] => Err(ParseError::NeedsValue { flag: Flag::Short(b'c') }));
test!(short_arg_eq: ["-c=4"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Short(b'c'), Some(&*os("4"))) ] }));
test!(short_arg_then: ["-c", "4"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Short(b'c'), Some(&*os("4"))) ] }));
test!(short_two_together: ["-lctwo"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Short(b'l'), None), (Flag::Short(b'c'), Some(&*os("two"))) ] }));
test!(short_two_equals: ["-lc=two"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Short(b'l'), None), (Flag::Short(b'c'), Some(&*os("two"))) ] }));
test!(short_two_next: ["-lc", "two"] => Ok(Matches { frees: vec![], flags: vec![ (Flag::Short(b'l'), None), (Flag::Short(b'c'), Some(&*os("two"))) ] }));
test!(bad_short: ["-l=equals"] => error ForbiddenValue { flag: Flag::Short(b'l') });
test!(short_none: ["-c"] => error NeedsValue { flag: Flag::Short(b'c') });
test!(short_arg_eq: ["-c=4"] => frees: [], flags: [(Flag::Short(b'c'), Some("4")) ]);
test!(short_arg_then: ["-c", "4"] => frees: [], flags: [(Flag::Short(b'c'), Some("4")) ]);
test!(short_two_together: ["-lctwo"] => frees: [], flags: [(Flag::Short(b'l'), None), (Flag::Short(b'c'), Some("two")) ]);
test!(short_two_equals: ["-lc=two"] => frees: [], flags: [(Flag::Short(b'l'), None), (Flag::Short(b'c'), Some("two")) ]);
test!(short_two_next: ["-lc", "two"] => frees: [], flags: [(Flag::Short(b'l'), None), (Flag::Short(b'c'), Some("two")) ]);
// Unknown args
test!(unknown_long: ["--quiet"] => Err(ParseError::UnknownArgument { attempt: os("quiet") }));
test!(unknown_long_eq: ["--quiet=shhh"] => Err(ParseError::UnknownArgument { attempt: os("quiet") }));
test!(unknown_short: ["-q"] => Err(ParseError::UnknownShortArgument { attempt: b'q' }));
test!(unknown_short_2nd: ["-lq"] => Err(ParseError::UnknownShortArgument { attempt: b'q' }));
test!(unknown_short_eq: ["-q=shhh"] => Err(ParseError::UnknownShortArgument { attempt: b'q' }));
test!(unknown_short_2nd_eq: ["-lq=shhh"] => Err(ParseError::UnknownShortArgument { attempt: b'q' }));
test!(unknown_long: ["--quiet"] => error UnknownArgument { attempt: os("quiet") });
test!(unknown_long_eq: ["--quiet=shhh"] => error UnknownArgument { attempt: os("quiet") });
test!(unknown_short: ["-q"] => error UnknownShortArgument { attempt: b'q' });
test!(unknown_short_2nd: ["-lq"] => error UnknownShortArgument { attempt: b'q' });
test!(unknown_short_eq: ["-q=shhh"] => error UnknownShortArgument { attempt: b'q' });
test!(unknown_short_2nd_eq: ["-lq=shhh"] => error UnknownShortArgument { attempt: b'q' });
}
@ -499,9 +537,8 @@ mod matches_test {
($name:ident: $input:expr, has $param:expr => $result:expr) => {
#[test]
fn $name() {
let frees = Vec::new();
let flags = $input.to_vec();
assert_eq!(Matches { frees, flags }.has(&$param), $result);
let flags = MatchedFlags { flags: $input.to_vec() };
assert_eq!(flags.has(&$param), $result);
}
};
}
@ -521,9 +558,8 @@ mod matches_test {
#[test]
fn only_count() {
let everything = os("everything");
let frees = Vec::new();
let flags = vec![ (Flag::Short(b'c'), Some(&*everything)) ];
assert_eq!(Matches { frees, flags }.get(&COUNT), Some(&*everything));
let flags = MatchedFlags { flags: vec![ (Flag::Short(b'c'), Some(&*everything)) ] };
assert_eq!(flags.get(&COUNT), Some(&*everything));
}
#[test]
@ -531,18 +567,18 @@ mod matches_test {
let everything = os("everything");
let nothing = os("nothing");
let frees = Vec::new();
let flags = vec![ (Flag::Short(b'c'), Some(&*everything)),
(Flag::Short(b'c'), Some(&*nothing)) ];
let flags = MatchedFlags {
flags: vec![ (Flag::Short(b'c'), Some(&*everything)),
(Flag::Short(b'c'), Some(&*nothing)) ]
};
assert_eq!(Matches { frees, flags }.get(&COUNT), Some(&*nothing));
assert_eq!(flags.get(&COUNT), Some(&*nothing));
}
#[test]
fn no_count() {
let frees = Vec::new();
let flags = Vec::new();
let flags = MatchedFlags { flags: Vec::new() };
assert!(!Matches { frees, flags }.has(&COUNT));
assert!(!flags.has(&COUNT));
}
}

View File

@ -7,7 +7,7 @@ use output::file_name::{Classify, FileStyle};
use output::time::TimeFormat;
use options::{flags, Misfire};
use options::parser::Matches;
use options::parser::MatchedFlags;
use fs::feature::xattr;
use info::filetype::FileExtensions;
@ -16,7 +16,7 @@ use info::filetype::FileExtensions;
impl View {
/// Determine which view to use and all of that views arguments.
pub fn deduce(matches: &Matches) -> Result<View, Misfire> {
pub fn deduce(matches: &MatchedFlags) -> Result<View, Misfire> {
let mode = Mode::deduce(matches)?;
let colours = Colours::deduce(matches)?;
let style = FileStyle::deduce(matches);
@ -28,7 +28,7 @@ impl View {
impl Mode {
/// Determine the mode from the command-line arguments.
pub fn deduce(matches: &Matches) -> Result<Mode, Misfire> {
pub fn deduce(matches: &MatchedFlags) -> Result<Mode, Misfire> {
use options::misfire::Misfire::*;
let long = || {
@ -182,7 +182,7 @@ impl TerminalWidth {
impl TableOptions {
fn deduce(matches: &Matches) -> Result<Self, Misfire> {
fn deduce(matches: &MatchedFlags) -> Result<Self, Misfire> {
Ok(TableOptions {
env: Environment::load_all(),
time_format: TimeFormat::deduce(matches)?,
@ -208,7 +208,7 @@ impl SizeFormat {
/// strings of digits in your head. Changing the format to anything else
/// involves the `--binary` or `--bytes` flags, and these conflict with
/// each other.
fn deduce(matches: &Matches) -> Result<SizeFormat, Misfire> {
fn deduce(matches: &MatchedFlags) -> Result<SizeFormat, Misfire> {
let binary = matches.has(&flags::BINARY);
let bytes = matches.has(&flags::BYTES);
@ -225,7 +225,7 @@ impl SizeFormat {
impl TimeFormat {
/// Determine how time should be formatted in timestamp columns.
fn deduce(matches: &Matches) -> Result<TimeFormat, Misfire> {
fn deduce(matches: &MatchedFlags) -> Result<TimeFormat, Misfire> {
pub use output::time::{DefaultFormat, ISOFormat};
const STYLES: &[&str] = &["default", "long-iso", "full-iso", "iso"];
@ -267,7 +267,7 @@ impl TimeTypes {
/// Its valid to show more than one column by passing in more than one
/// option, but passing *no* options means that the user just wants to
/// see the default set.
fn deduce(matches: &Matches) -> Result<TimeTypes, Misfire> {
fn deduce(matches: &MatchedFlags) -> Result<TimeTypes, Misfire> {
let possible_word = matches.get(&flags::TIME);
let modified = matches.has(&flags::MODIFIED);
let created = matches.has(&flags::CREATED);
@ -335,7 +335,7 @@ impl Default for TerminalColours {
impl TerminalColours {
/// Determine which terminal colour conditions to use.
fn deduce(matches: &Matches) -> Result<TerminalColours, Misfire> {
fn deduce(matches: &MatchedFlags) -> Result<TerminalColours, Misfire> {
const COLOURS: &[&str] = &["always", "auto", "never"];
let word = match matches.get(&flags::COLOR).or_else(|| matches.get(&flags::COLOUR)) {
@ -360,7 +360,7 @@ impl TerminalColours {
impl Colours {
fn deduce(matches: &Matches) -> Result<Colours, Misfire> {
fn deduce(matches: &MatchedFlags) -> Result<Colours, Misfire> {
use self::TerminalColours::*;
let tc = TerminalColours::deduce(matches)?;
@ -377,7 +377,7 @@ impl Colours {
impl FileStyle {
fn deduce(matches: &Matches) -> FileStyle {
fn deduce(matches: &MatchedFlags) -> FileStyle {
let classify = Classify::deduce(matches);
let exts = FileExtensions;
FileStyle { classify, exts }
@ -385,7 +385,7 @@ impl FileStyle {
}
impl Classify {
fn deduce(matches: &Matches) -> Classify {
fn deduce(matches: &MatchedFlags) -> Classify {
if matches.has(&flags::CLASSIFY) { Classify::AddFileIndicators }
else { Classify::JustFilenames }
}
@ -428,7 +428,7 @@ mod test {
let bits = $inputs.as_ref().into_iter().map(|&o| os(o)).collect::<Vec<OsString>>();
let results = Args(TEST_ARGS).parse(bits.iter());
assert_eq!($type::deduce(results.as_ref().unwrap()), $result);
assert_eq!($type::deduce(&results.unwrap().flags), $result);
}
};
}