/
parse_args.rs
133 lines (118 loc) Β· 3.69 KB
/
parse_args.rs
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use humantime::Duration;
#[cfg(not(target_os = "emscripten"))]
use humantime::parse_duration;
use std::time::Instant;
#[cfg(not(target_os = "emscripten"))]
fn is_parse_duration_format(v: String) -> Result<(), String> {
if parse_duration(&v).is_ok() {
Ok(())
} else {
Err(String::from("Couldn't parse the time format"))
}
}
pub struct AppConfig {
pub list_modules_and_exit: bool,
pub modules: Vec<String>,
pub exit_after: Option<Duration>,
pub started_at: Instant,
}
impl AppConfig {
/// Check whether it's time to stop running.
pub fn should_exit(&self) -> bool {
// Check whether CTRL-C was pressed.
#[cfg(not(target_os = "emscripten"))]
{
use std::sync::atomic::Ordering;
use crate::CTRLC_PRESSED;
if CTRLC_PRESSED.load(Ordering::SeqCst) {
return true;
}
}
// Check if maximum running time is exceeded.
if let Some(ea) = self.exit_after {
if self.started_at.elapsed() > *ea {
return true;
}
}
false
}
}
#[cfg(not(target_os = "emscripten"))]
pub fn parse_args(all_modules: &[&str]) -> AppConfig {
use clap::{App, Arg, AppSettings};
let matches = App::new(crate_name!())
.version(crate_version!())
.author(crate_authors!())
.about(crate_description!())
.global_setting(AppSettings::ColoredHelp)
.arg(
Arg::with_name("list")
.short("l")
.long("list-modules")
.help("List available modules"),
)
.arg(
Arg::with_name("modules")
.short("m")
.long("modules")
.multiple(true)
.value_name("MODULE")
.takes_value(true)
.possible_values(all_modules)
.help("Run only these modules"),
)
.arg(
Arg::with_name("exitafter")
.short("e")
.long("exitafter")
.value_name("EXITAFTER")
.takes_value(true)
.validator(is_parse_duration_format)
.help("Exit after running for this long (format example: 2h10min)"),
)
.get_matches();
let list_modules_and_exit = matches.is_present("list");
let modules_to_run = if matches.is_present("modules") {
matches
.values_of("modules")
.unwrap()
.map(|x| x.to_string())
.collect()
} else {
all_modules.iter().map(|x| x.to_string()).collect()
};
let exit_after = value_t!(matches, "exitafter", Duration).ok();
AppConfig {
list_modules_and_exit,
modules: modules_to_run,
exit_after,
started_at: Instant::now(),
}
}
#[cfg(target_os = "emscripten")]
pub fn parse_args(all_modules: &[&str]) -> AppConfig {
use stdweb::web;
use url::Url;
let mut temp_modules = vec![];
let location = web::document().location().unwrap();
let parsed_url = Url::parse(&location.href().unwrap()).unwrap();
let pairs = parsed_url.query_pairs();
let filtered = pairs.filter(|&(ref x, _)| x == "module");
for (_, query_val) in filtered {
let actual_val = &&*query_val;
if all_modules.contains(actual_val) {
temp_modules.push(actual_val.to_string());
}
}
let modules_to_run = if temp_modules.is_empty() {
all_modules.iter().map(|x| x.to_string()).collect()
} else {
temp_modules
};
AppConfig {
list_modules_and_exit: false,
modules: modules_to_run,
exit_after: None,
started_at: Instant::now(),
}
}