1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use crate::Method;
use clap::{
crate_description, crate_name, crate_version, App, AppSettings, Arg, Shell, SubCommand,
};
use itertools::Itertools;
use strum::{IntoEnumIterator, VariantNames};
use tracing::instrument;
pub mod args {
pub const COMPLETIONS: &str = "completions";
pub const SHELL: &str = "shell";
pub const PATHS: &str = "paths";
}
impl Method {
fn helptext(&self) -> &'static str {
match self {
Method::Accessed => "Sort by access on this file or directory",
Method::Created => "Sort by creation on this volume",
Method::Modified => "Sort by modification of the file or directory",
}
}
}
#[instrument]
pub fn app<'a, 'b>() -> App<'a, 'b> {
use args::*;
App::new(crate_name!())
.version(crate_version!())
.about(crate_description!())
.setting(AppSettings::ColorAuto)
.setting(AppSettings::SubcommandRequiredElseHelp)
.usage(
format!(
"{} <{}> [PATH...]>\n OR:\n {} completions <{}>",
crate_name!(),
Method::VARIANTS.iter().format(" | "),
crate_name!(),
Shell::variants().iter().format(" | ")
)
.into_static_str(),
)
.subcommand(
SubCommand::with_name(COMPLETIONS)
.about("Print out a shell completion script for a given shell")
.arg(
Arg::with_name(SHELL)
.takes_value(true)
.value_name("shell")
.possible_values(Shell::variants().as_ref())
.required(true),
),
)
.subcommands(Method::iter().map(|method| {
SubCommand::with_name(method.as_ref())
.about(method.helptext())
.display_order(0)
.arg(
Arg::with_name(PATHS)
.help("Candidate paths. May be files or folders. If none supplied, will be read from stdin (one path per line)")
.multiple(true)
)
}))
}
trait IntoStaticStr {
fn into_static_str(self) -> &'static str;
}
impl IntoStaticStr for String {
fn into_static_str(self) -> &'static str {
Box::leak(self.into_boxed_str())
}
}