Skip to content

Commit

Permalink
Use vec of function pointers over sorting closure.
Browse files Browse the repository at this point in the history
  • Loading branch information
Allen Hsu authored and meain committed Sep 12, 2020
1 parent ae11a29 commit 85bee8b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 47 deletions.
4 changes: 2 additions & 2 deletions src/app.rs
Expand Up @@ -191,8 +191,8 @@ pub fn build() -> App<'static, 'static> {
)
.arg(
Arg::with_name("classic")
.long("classic")
.help("Enable classic mode (no colors or icons)"),
.long("classic")
.help("Enable classic mode (no colors or icons)"),
)
.arg(
Arg::with_name("no-symlink")
Expand Down
10 changes: 5 additions & 5 deletions src/core.rs
@@ -1,6 +1,6 @@
use crate::color::{self, Colors};
use crate::display;
use crate::flags::{Display, Flags, IconTheme, Layout, WhenFlag};
use crate::flags::{Display, Flags, IconTheme, Layout, SortOrder, WhenFlag};
use crate::icon::{self, Icons};
use crate::meta::Meta;
use crate::{print_error, print_output, sort};
Expand All @@ -19,7 +19,7 @@ pub struct Core {
icons: Icons,
//display: Display,
colors: Colors,
sorter: sort::Sorter,
sorters: Vec<(SortOrder, sort::SortFn)>,
}

impl Core {
Expand Down Expand Up @@ -59,14 +59,14 @@ impl Core {
inner_flags.layout = Layout::OneLine;
};

let sorter = sort::create_sorter(&flags);
let sorters = sort::assemble_sorters(&flags);

Self {
flags,
//display: Display::new(inner_flags),
colors: Colors::new(color_theme),
icons: Icons::new(icon_theme),
sorter,
sorters,
}
}

Expand Down Expand Up @@ -122,7 +122,7 @@ impl Core {
}

fn sort(&self, metas: &mut Vec<Meta>) {
metas.sort_unstable_by(|a, b| (self.sorter)(a, b));
metas.sort_unstable_by(|a, b| sort::by_meta(&self.sorters, a, b));

for meta in metas {
if let Some(ref mut content) = meta.content {
Expand Down
79 changes: 39 additions & 40 deletions src/sort.rs
Expand Up @@ -2,11 +2,9 @@ use crate::flags::{DirOrderFlag, Flags, SortFlag, SortOrder};
use crate::meta::Meta;
use std::cmp::Ordering;

pub type Sorter = Box<dyn Fn(&Meta, &Meta) -> Ordering>;

pub fn create_sorter(flags: &Flags) -> Sorter {
type SortFn = fn(&Meta, &Meta) -> Ordering;
pub type SortFn = fn(&Meta, &Meta) -> Ordering;

pub fn assemble_sorters(flags: &Flags) -> Vec<(SortOrder, SortFn)> {
let mut sorters: Vec<(SortOrder, SortFn)> = vec![];
match flags.directory_order {
DirOrderFlag::First => {
Expand All @@ -23,21 +21,22 @@ pub fn create_sorter(flags: &Flags) -> Sorter {
SortFlag::Time => by_date,
};
sorters.push((flags.sort_order, other_sort));
sorters
}

Box::new(move |a, b| {
for (direction, sorter) in sorters.iter() {
match (sorter)(a, b) {
Ordering::Equal => continue,
ordering => {
return match direction {
SortOrder::Reverse => ordering.reverse(),
SortOrder::Default => ordering,
}
pub fn by_meta(sorters: &[(SortOrder, SortFn)], a: &Meta, b: &Meta) -> Ordering {
for (direction, sorter) in sorters.iter() {
match (sorter)(a, b) {
Ordering::Equal => continue,
ordering => {
return match direction {
SortOrder::Reverse => ordering.reverse(),
SortOrder::Default => ordering,
}
}
}
Ordering::Equal
})
}
Ordering::Equal
}

fn with_dirs_first(a: &Meta, b: &Meta) -> Ordering {
Expand Down Expand Up @@ -65,7 +64,7 @@ mod tests {
use tempfile::tempdir;

#[test]
fn test_sort_create_sorter_by_name_with_dirs_first() {
fn test_sort_assemble_sorters_by_name_with_dirs_first() {
let tmp_dir = tempdir().expect("failed to create temp dir");

// Create the file;
Expand All @@ -82,18 +81,18 @@ mod tests {
flags.directory_order = DirOrderFlag::First;

// Sort with the dirs first
let sorter = create_sorter(&flags);
assert_eq!((sorter)(&meta_a, &meta_z), Ordering::Greater);
let sorter = assemble_sorters(&flags);
assert_eq!(by_meta(&sorter, &meta_a, &meta_z), Ordering::Greater);

// Sort with the dirs first (the dirs stay first)
flags.sort_order = SortOrder::Reverse;

let sorter = create_sorter(&flags);
assert_eq!((sorter)(&meta_a, &meta_z), Ordering::Greater);
let sorter = assemble_sorters(&flags);
assert_eq!(by_meta(&sorter, &meta_a, &meta_z), Ordering::Greater);
}

#[test]
fn test_sort_create_sorter_by_name_with_files_first() {
fn test_sort_assemble_sorters_by_name_with_files_first() {
let tmp_dir = tempdir().expect("failed to create temp dir");

// Create the file;
Expand All @@ -110,16 +109,16 @@ mod tests {
flags.directory_order = DirOrderFlag::Last;

// Sort with file first
let sorter = create_sorter(&flags);
assert_eq!((sorter)(&meta_a, &meta_z), Ordering::Less);
let sorter = assemble_sorters(&flags);
assert_eq!(by_meta(&sorter, &meta_a, &meta_z), Ordering::Less);

// Sort with file first reversed (thie files stay first)
let sorter = create_sorter(&flags);
assert_eq!((sorter)(&meta_a, &meta_z), Ordering::Less);
let sorter = assemble_sorters(&flags);
assert_eq!(by_meta(&sorter, &meta_a, &meta_z), Ordering::Less);
}

#[test]
fn test_sort_create_sorter_by_name_unordered() {
fn test_sort_assemble_sorters_by_name_unordered() {
let tmp_dir = tempdir().expect("failed to create temp dir");

// Create the file;
Expand All @@ -136,18 +135,18 @@ mod tests {
flags.directory_order = DirOrderFlag::None;

// Sort by name unordered
let sorter = create_sorter(&flags);
assert_eq!((sorter)(&meta_a, &meta_z), Ordering::Less);
let sorter = assemble_sorters(&flags);
assert_eq!(by_meta(&sorter, &meta_a, &meta_z), Ordering::Less);

// Sort by name unordered
flags.sort_order = SortOrder::Reverse;

let sorter = create_sorter(&flags);
assert_eq!((sorter)(&meta_a, &meta_z), Ordering::Greater);
let sorter = assemble_sorters(&flags);
assert_eq!(by_meta(&sorter, &meta_a, &meta_z), Ordering::Greater);
}

#[test]
fn test_sort_create_sorter_by_name_unordered_2() {
fn test_sort_assemble_sorters_by_name_unordered_2() {
let tmp_dir = tempdir().expect("failed to create temp dir");

// Create the file;
Expand All @@ -164,18 +163,18 @@ mod tests {
flags.directory_order = DirOrderFlag::None;

// Sort by name unordered
let sorter = create_sorter(&flags);
assert_eq!((sorter)(&meta_a, &meta_z), Ordering::Greater);
let sorter = assemble_sorters(&flags);
assert_eq!(by_meta(&sorter, &meta_a, &meta_z), Ordering::Greater);

// Sort by name unordered reversed
flags.sort_order = SortOrder::Reverse;

let sorter = create_sorter(&flags);
assert_eq!((sorter)(&meta_a, &meta_z), Ordering::Less);
let sorter = assemble_sorters(&flags);
assert_eq!(by_meta(&sorter, &meta_a, &meta_z), Ordering::Less);
}

#[test]
fn test_sort_create_sorter_by_time() {
fn test_sort_assemble_sorters_by_time() {
let tmp_dir = tempdir().expect("failed to create temp dir");

// Create the file;
Expand Down Expand Up @@ -213,12 +212,12 @@ mod tests {
flags.sort_by = SortFlag::Time;

// Sort by time
let sorter = create_sorter(&flags);
assert_eq!((sorter)(&meta_a, &meta_z), Ordering::Less);
let sorter = assemble_sorters(&flags);
assert_eq!(by_meta(&sorter, &meta_a, &meta_z), Ordering::Less);

// Sort by time reversed
flags.sort_order = SortOrder::Reverse;
let sorter = create_sorter(&flags);
assert_eq!((sorter)(&meta_a, &meta_z), Ordering::Greater);
let sorter = assemble_sorters(&flags);
assert_eq!(by_meta(&sorter, &meta_a, &meta_z), Ordering::Greater);
}
}

0 comments on commit 85bee8b

Please sign in to comment.