Merge pull request #932 from alsuren/sort--stable

implement sort --stable
This commit is contained in:
Nathan Ross 2016-08-03 06:52:39 -04:00 committed by GitHub
commit 63c17e5b42
6 changed files with 66 additions and 6 deletions

View file

@ -43,6 +43,7 @@ struct Settings {
mode: SortMode,
reverse: bool,
outfile: Option<String>,
stable: bool,
unique: bool,
check: bool,
}
@ -53,6 +54,7 @@ impl Default for Settings {
mode: SortMode::Default,
reverse: false,
outfile: None,
stable: false,
unique: false,
check: false,
}
@ -70,6 +72,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
opts.optflag("h", "help", "display this help and exit");
opts.optflag("", "version", "output version information and exit");
opts.optopt("o", "output", "write output to FILENAME instead of stdout", "FILENAME");
opts.optflag("s", "stable", "stabilize sort by disabling last-resort comparison");
opts.optflag("u", "unique", "output only the first of an equal run");
opts.optflag("V", "version-sort", "Sort by SemVer version number, eg 1.12.2 > 1.1.2");
opts.optflag("c", "check", "check for sorted input; do not sort");
@ -112,6 +115,7 @@ With no FILE, or when FILE is -, read standard input.", NAME, VERSION);
settings.reverse = matches.opt_present("reverse");
settings.outfile = matches.opt_str("output");
settings.stable = matches.opt_present("stable");
settings.unique = matches.opt_present("unique");
settings.check = matches.opt_present("check");
@ -146,14 +150,25 @@ fn exec(files: Vec<String>, settings: &Settings) -> i32 {
let original_lines = lines.to_vec();
match settings.mode {
SortMode::Numeric => lines.sort_by(numeric_compare),
SortMode::HumanNumeric => lines.sort_by(human_numeric_size_compare),
SortMode::Month => lines.sort_by(month_compare),
SortMode::Version => lines.sort_by(version_compare),
SortMode::Default => lines.sort()
let mut compare_fns = Vec::new();
compare_fns.push(match settings.mode {
SortMode::Numeric => numeric_compare,
SortMode::HumanNumeric => human_numeric_size_compare,
SortMode::Month => month_compare,
SortMode::Version => version_compare,
SortMode::Default => String::cmp
});
if !settings.stable {
match settings.mode {
SortMode::Default => {}
_ => compare_fns.push(String::cmp)
}
}
sort_by(&mut lines, compare_fns);
if settings.unique {
lines.dedup()
}
@ -178,6 +193,20 @@ fn exec(files: Vec<String>, settings: &Settings) -> i32 {
}
fn sort_by<F>(lines: &mut Vec<String>, compare_fns: Vec<F>)
where F: Fn( &String, &String ) -> Ordering
{
lines.sort_by(|a, b| {
for compare_fn in &compare_fns {
let cmp = compare_fn(a, b);
if cmp != Ordering::Equal {
return cmp;
}
}
return Ordering::Equal;
})
}
/// Parse the beginning string into an f64, returning -inf instead of NaN on errors.
fn permissive_f64_parse(a: &str) -> f64 {
// Maybe should be split on non-digit, but then 10e100 won't parse properly.

View file

@ -3,5 +3,8 @@ Jan Lorem ipsum dolor sit amet
mar laboris nisi ut aliquip ex ea
May sed do eiusmod tempor incididunt
JUN nostrud exercitation ullamco
Jul 1 should remain 2,1,3
Jul 2 these three lines
Jul 3 if --stable is provided
Oct ut labore et dolore magna aliqua
Dec consectetur adipiscing elit

View file

@ -5,3 +5,6 @@ Oct ut labore et dolore magna aliqua
N/A Ut enim ad minim veniam, quis
JUN nostrud exercitation ullamco
mar laboris nisi ut aliquip ex ea
Jul 2 these three lines
Jul 1 should remain 2,1,3
Jul 3 if --stable is provided

View file

@ -0,0 +1,10 @@
N/A Ut enim ad minim veniam, quis
Jan Lorem ipsum dolor sit amet
mar laboris nisi ut aliquip ex ea
May sed do eiusmod tempor incididunt
JUN nostrud exercitation ullamco
Jul 2 these three lines
Jul 1 should remain 2,1,3
Jul 3 if --stable is provided
Oct ut labore et dolore magna aliqua
Dec consectetur adipiscing elit

10
tests/fixtures/sort/month_stable.txt vendored Normal file
View file

@ -0,0 +1,10 @@
Jan Lorem ipsum dolor sit amet
Dec consectetur adipiscing elit
May sed do eiusmod tempor incididunt
Oct ut labore et dolore magna aliqua
N/A Ut enim ad minim veniam, quis
JUN nostrud exercitation ullamco
mar laboris nisi ut aliquip ex ea
Jul 2 these three lines
Jul 1 should remain 2,1,3
Jul 3 if --stable is provided

View file

@ -41,6 +41,11 @@ fn test_month_default() {
test_helper("month_default", "-M");
}
#[test]
fn test_month_stable() {
test_helper("month_stable", "-Ms");
}
#[test]
fn test_default_unsorted_ints() {
test_helper("default_unsorted_ints", "");