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
134
mod arg;
mod error;
mod help;
mod seqalin;
pub mod cli;
pub mod proc;
pub use arg::Arg;
pub use cli::stage;
pub use cli::Cli;
pub use help::Help;
pub use proc::{Command, Subcommand};
pub use std::process::ExitCode;
#[cfg(test)]
mod tests {
use super::*;
use stage::Memory;
/// Helper test `fn` to write vec of &str as iterator for Cli parameter.
fn args<'a>(args: Vec<&'a str>) -> Box<dyn Iterator<Item = String> + 'a> {
Box::new(args.into_iter().map(|f| f.to_string()).into_iter())
}
mod add {
use super::*;
mod ok {
use super::*;
#[derive(PartialEq, Debug)]
struct Add {
lhs: u8,
rhs: u8,
verbose: bool,
}
impl Add {
fn run(&self) -> u16 {
self.lhs as u16 + self.rhs as u16
}
}
impl Command for Add {
fn interpret(cli: &mut Cli<Memory>) -> cli::Result<Self> {
// set help text in case of an error
cli.help(Help::with(String::new()))?;
let radd = Add {
verbose: cli.check(Arg::flag("verbose"))?,
lhs: cli.require(Arg::positional("lhs"))?,
rhs: cli.require(Arg::positional("rhs"))?,
};
// optional: verify the cli has no additional arguments if this is the top-level command being parsed
cli.empty()?;
Ok(radd)
}
fn execute(self) -> proc::Result {
let sum: u16 = self.run();
if self.verbose == true {
println!("{} + {} = {}", self.lhs, self.rhs, sum);
} else {
println!("{}", sum);
}
Ok(())
}
}
#[test]
fn it_add_program() {
let mut cli = Cli::new()
.threshold(4)
.parse(args(vec!["add", "45", "17"]))
.save();
let program = Add::interpret(&mut cli).unwrap();
std::mem::drop(cli);
assert_eq!(program.run(), 62);
}
}
mod bad {
use super::*;
#[derive(PartialEq, Debug)]
struct Add {
lhs: u8,
rhs: u8,
verbose: bool,
}
impl Add {
fn run(&self) -> u16 {
self.lhs as u16 + self.rhs as u16
}
}
impl Command for Add {
fn interpret(cli: &mut Cli<Memory>) -> cli::Result<Self> {
// set help text in case of an error
cli.help(Help::with(String::new()))?;
let radd = Add {
lhs: cli.require(Arg::positional("lhs"))?,
verbose: cli.check(Arg::flag("verbose"))?,
rhs: cli.require(Arg::positional("rhs"))?,
};
// optional: verify the cli has no additional arguments if this is the top-level command being parsed
cli.empty()?;
Ok(radd)
}
fn execute(self) -> proc::Result {
let sum: u16 = self.run();
if self.verbose == true {
println!("{} + {} = {}", self.lhs, self.rhs, sum);
} else {
println!("{}", sum);
}
Ok(())
}
}
#[test]
#[should_panic]
fn it_add_program() {
let mut cli = Cli::new()
.threshold(4)
.parse(args(vec!["add", "45", "17"]))
.save();
let _ = Add::interpret(&mut cli);
}
}
}
}