1use combu::{command::presets, done, ActionError, ActionResult, Command, Context, Flag, FlagValue};
2fn main() {
13 let _ = root_command().run_from_args(std::env::args().collect());
14}
15
16fn root_command() -> Command {
17 Command::with_name("multi")
18 .description("root command sample: arg printer")
19 .usage(presets::usage("multi"))
20 .common_flag(Flag::new_bool("help").short_alias('h'))
21 .common_flag(Flag::new_bool("reverse").short_alias('r'))
22 .local_flag(
23 Flag::new_bool("by-char")
24 .short_alias('c')
25 .description("process at char units"),
26 )
27 .action(print_args)
28 .sub_command(add_command())
29 .sub_command(sub_command())
30}
31fn call_help(c: &Context, cur_cmd: &Command) -> Result<ActionResult, ActionError> {
32 println!("{}", presets::func::help(cur_cmd, c));
33 done!()
34}
35fn print_args(current_command: Command, context: Context) -> Result<ActionResult, ActionError> {
36 if called_help(&context, ¤t_command) {
37 return call_help(&context, ¤t_command);
38 }
39 let r: bool =
40 context.get_flag_value_of("reverse", ¤t_command) == Some(FlagValue::Bool(true));
41 let c: bool =
42 context.get_flag_value_of("by-char", ¤t_command) == Some(FlagValue::Bool(true));
43 let str = {
44 let str = if r && !c {
45 context
46 .args
47 .iter()
48 .rev()
49 .fold(String::new(), |c, arg| c + arg)
50 } else {
51 context.args.iter().fold(String::new(), |c, arg| c + arg)
52 };
53 if c {
54 str.chars().rev().collect::<String>()
55 } else {
56 str
57 }
58 };
59
60 println!("{}", str);
61
62 Ok(ActionResult::Done)
63}
64
65fn called_help(c: &Context, cc: &Command) -> bool {
66 Some(FlagValue::Bool(true)) == c.get_flag_value_of("help", cc)
67}
68
69fn add_command() -> Command {
70 Command::new()
71 .name("add")
72 .alias("a")
73 .action(add_action)
74 .local_flag(Flag::new_bool("detail").short_alias('d'))
75}
76
77fn add_action(cmd: Command, c: Context) -> Result<ActionResult, ActionError> {
78 if called_help(&c, &cmd) {
79 return call_help(&c, &cmd);
80 }
81 let f = |(str, sum), num: f64| (format!("{} {} +", str, num), sum + num);
82 let (mut str, sum): (String, f64) =
83 if c.get_flag_value_of("reverse", &cmd) == Some(FlagValue::Bool(true)) {
84 c.args
85 .iter()
86 .rev()
87 .filter_map(|arg| arg.parse().ok())
88 .fold((String::new(), 0.0), f)
89 } else {
90 c.args
91 .iter()
92 .filter_map(|arg| arg.parse().ok())
93 .fold((String::new(), 0.0), f)
94 };
95 str.pop();
96 str.pop();
97
98 if c.get_flag_value_of("detail", &cmd).unwrap().is_bool_true() {
99 println!("{} = {}", str, sum);
100 } else {
101 println!("{}", sum);
102 }
103 Ok(ActionResult::Done)
104}
105
106fn sub_command() -> Command {
107 Command::new()
108 .name("sub")
109 .alias("s")
110 .action(sub_action)
111 .local_flag(Flag::new_bool("sort").short_alias('s'))
112}
113
114fn sub_action(cmd: Command, c: Context) -> Result<ActionResult, ActionError> {
115 if called_help(&c, &cmd) {
116 return call_help(&c, &cmd);
117 }
118 let f = |(str, sum), (index, num): (usize, f64)| {
119 (
120 format!("{} {} -", str, num),
121 if index < 1 { num } else { sum - num },
122 )
123 };
124 let filter_map_f = |arg: &String| arg.parse().ok();
125 let (mut str, result): (String, f64) =
126 if c.get_flag_value_of("reverse", &cmd) == Some(FlagValue::Bool(true)) {
127 c.args
128 .iter()
129 .rev()
130 .filter_map(filter_map_f)
131 .enumerate()
132 .fold((String::new(), 0.0), f)
133 } else if c.get_flag_value_of("sort", &cmd).unwrap().is_bool_true() {
134 let mut fvec = c.args.iter().filter_map(filter_map_f).collect::<Vec<f64>>();
135 fvec.sort_by(|a, b| a.partial_cmp(b).unwrap());
136 fvec
137 .iter_mut()
138 .enumerate()
139 .fold((String::new(), 0.0), |s, (index, fl)| f(s, (index, *fl)))
140 } else {
141 c.args
142 .iter()
143 .filter_map(filter_map_f)
144 .enumerate()
145 .fold((String::new(), 0.0), f)
146 };
147 str.pop();
148 str.pop();
149
150 println!("{} = {}", str, result);
151
152 Ok(ActionResult::Done)
153}