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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
use cassiopeia::{error::ParseResult, meta, Cassiopeia};
use clap::{App, Arg, SubCommand};
fn main() {
let cli = App::new(meta::NAME)
.version(meta::VERSION)
.about(meta::ABOUT)
.after_help("To learn more on how to use cassiopeia, check out the documentation \
at https://git.spacekookie.de/kookienomicon/tree/apps/cassiopeia
If you want to report a bug, please do so on my mailing list: lists.sr.ht/~spacekookie/public-inbox")
.author(meta::AUTHOR)
.max_term_width(120)
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
.global_settings(&[
clap::AppSettings::DisableHelpSubcommand,
clap::AppSettings::VersionlessSubcommands,
])
.arg(
Arg::with_name(meta::ARG_FILE)
.short("f")
.long("file")
.help(meta::ARG_FILE_ABOUT)
.default_value("./time.cass")
.takes_value(true),
)
.subcommand(SubCommand::with_name(meta::CMD_UPDATE).about(meta::CMD_UPDATE_ABOUT))
.subcommand(
SubCommand::with_name(meta::CMD_START)
.about(meta::CMD_START_ABOUT)
.arg(Arg::with_name(meta::ARG_ROUNDING).short("r").long("no-round").help(meta::ARG_ROUNDING_ABOUT)),
)
.subcommand(
SubCommand::with_name(meta::CMD_STOP)
.about(meta::CMD_STOP_ABOUT)
.arg(Arg::with_name(meta::ARG_ROUNDING).short("r").long("no-round").help(meta::ARG_ROUNDING_ABOUT)),
)
.subcommand(
SubCommand::with_name(meta::CMD_INVOICE)
.about(meta::CMD_INVOICE_ABOUT)
.arg(
Arg::with_name(meta::ARG_CLIENT)
.short("c")
.long("client")
.takes_value(true)
.help(meta::ARG_CLIENT_ABOUT),
)
.arg(
Arg::with_name(meta::ARG_PROJECT)
.short("p")
.long("project")
.takes_value(true)
.help(meta::ARG_PROJECT_ABOUT),
)
.arg(
Arg::with_name(meta::ARG_GEN_YAML)
.short("g")
.long("gen")
.help(meta::ARG_GEN_YAML_ABOUT),
)
.arg(
Arg::with_name(meta::ARG_CLIENT_DB)
.long("client-db")
.takes_value(true)
.help(meta::ARG_CLIENT_DB_ABOUT),
)
)
.subcommand(SubCommand::with_name(meta::CMD_STAT).about(meta::CMD_STAT_ABOUT))
.get_matches();
let cass_file = cli.value_of(meta::ARG_FILE).unwrap();
let mut cass = match Cassiopeia::load(cass_file) {
Ok(cf) => cf,
Err(e) => {
eprintln!("{}", e);
std::process::exit(1);
}
};
// Parse the matches generated by clap
match cli.subcommand() {
("start", Some(ops)) => {
let round = ops.is_present(meta::ARG_ROUNDING);
run_command(|| cass.start(!round));
}
("stop", Some(ops)) => {
let round = ops.is_present(meta::ARG_ROUNDING);
run_command(|| cass.stop(!round));
}
("invoice", _) => {
eprintln!("Invoice command only partially implemented! No generation is supported");
run_command(|| cass.invoice().run());
}
("update", _) => run_command(|| cass.update()),
(meta::CMD_STAT, _) => run_command(|| {
let stats = cass.stat()?;
println!("{}", stats);
Ok(())
}),
(_, _) => todo!(),
}
}
/// Run a closure and print the associated error message
///
/// Set the exit code for the program.
fn run_command<F>(mut cmd: F)
where
F: FnMut() -> ParseResult<()>,
{
match cmd() {
Ok(_) => std::process::exit(0),
Err(e) => {
eprintln!("{}", e);
std::process::exit(2);
}
}
}
|