Skip to content

Commit

Permalink
ls: add a --sort={none,name,time} option
Browse files Browse the repository at this point in the history
  • Loading branch information
davvid committed Dec 8, 2024
1 parent c589fa1 commit adb4f66
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
5 changes: 5 additions & 0 deletions doc/src/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Upcoming

**Features**:

- `garden ls` now has a `-s | --sort` option that allows you to sort
trees by name or modification time.

**Development**:

- Use of the [unmaintained](https://rustsec.org/advisories/RUSTSEC-2024-0388)
Expand Down
49 changes: 49 additions & 0 deletions src/cmds/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ pub struct ListOptions {
/// Print trees in reverse order
#[arg(short, long, default_value_t = false)]
reverse: bool,
/// Sort trees using the specified mode [none, name, time]
#[arg(
long,
short,
require_equals = true,
num_args = 0..=1,
default_value_t = model::TreeSortMode::None,
default_missing_value = "name",
value_name = "MODE",
value_parser = model::TreeSortMode::parse_from_str,
)]
sort: model::TreeSortMode,
/// Increase verbosity level (default: 0)
#[arg(short, long, action = clap::ArgAction::Count)]
verbose: u8,
Expand Down Expand Up @@ -58,6 +70,43 @@ fn list(app_context: &model::ApplicationContext, options: &ListOptions) -> Resul
// Resolve the tree query into a vector of tree contexts.
let mut contexts =
query::resolve_and_filter_trees(app_context, config, query, &options.trees);
match options.sort {
model::TreeSortMode::None => (),
model::TreeSortMode::Name => {
contexts.sort_by(|context_a, context_b| context_a.tree.cmp(&context_b.tree));
}
model::TreeSortMode::Time => {
contexts.sort_by(|context_a, context_b| {
let config_a = match context_a.config {
Some(config_id) => app_context.get_config(config_id),
None => config,
};
let config_b = match context_b.config {
Some(config_id) => app_context.get_config(config_id),
None => config,
};
match (
config_a
.trees
.get(&context_a.tree)
.and_then(|tree| tree.pathbuf())
.and_then(|pathbuf| pathbuf.metadata().ok())
.and_then(|metadata| metadata.modified().ok()),
config_b
.trees
.get(&context_b.tree)
.and_then(|tree| tree.pathbuf())
.and_then(|pathbuf| pathbuf.metadata().ok())
.and_then(|metadata| metadata.modified().ok()),
) {
(Some(a), Some(b)) => a.cmp(&b),
(None, Some(_)) => std::cmp::Ordering::Less,
(Some(_), None) => std::cmp::Ordering::Greater,
(None, None) => std::cmp::Ordering::Equal,
}
});
}
}
if options.reverse {
contexts.reverse();
}
Expand Down
25 changes: 25 additions & 0 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1408,6 +1408,31 @@ impl ColorMode {
}
}

#[derive(
Clone,
Debug,
Default,
PartialEq,
Eq,
strum_macros::EnumString,
strum_macros::Display,
strum_macros::VariantNames,
)]
#[strum(ascii_case_insensitive, serialize_all = "kebab-case")]
pub enum TreeSortMode {
#[default]
None,
Name,
Time,
}

impl TreeSortMode {
/// Parse a color mode from a string using strum's from_str().
pub(crate) fn parse_from_str(string: &str) -> Result<TreeSortMode, String> {
TreeSortMode::from_str(string).map_err(|_| format!("choices are {:?}", Self::VARIANTS))
}
}

#[derive(Debug)]
pub struct ApplicationContext {
pub options: cli::MainOptions,
Expand Down

0 comments on commit adb4f66

Please sign in to comment.