[go: up one dir, main page]

rara/
cmd.rs

1use combu::{
2    Command, Context, Flag, FlagValue, action_result, alias, checks, commands, copyright,
3    crate_authors, crate_description, crate_name, crate_version, done, flags, license, output_help,
4    vector::flag::FlagSearch,
5};
6
7use crate::pwgen;
8
9pub fn new() -> Command {
10    Command::with_all_field(
11        crate_name!().into(),
12        Some(act),
13        crate_authors!().into(),
14        copyright!(from_crate, 2022),
15        license!("MIT License",file_path=>"../LICENSE"),
16        Some(crate_description!().into()),
17        "rara [OPTIONS]".into(),
18        flags![
19            [
20                [length]=>[>int?20,="password length option. default: 20",-l,--len]
21            ],
22            [
23                [number]=>[>int?7,="password number option. default: 7",-n,--num]
24            ],
25            [
26                [include]=>[>String,="chooses chars indicate type password include. Types are alphabet(a),number(n),symbol(s) and default(d). You can specify multiple chars(ex: an). default=ans",-i,?"d"]
27            ],
28            [
29                [exclude]=>[
30                    >String?"",
31                    ="Password will generate without chars that is specidied by this flag",-e
32                ]
33            ],
34            [
35                [custom]=>[
36                    >String?"",
37                    ="Password will generate with only chars that is specidied by this flag. this option is inputted, include option is disabled. default: disable",-c,-m,--cstm
38                ]
39            ]
40        ],
41        flags!(help, version, license),
42        alias!(),
43        crate_version!().into(),
44        commands!(),
45    )
46}
47
48fn act(cmd: Command, ctx: Context) -> action_result!() {
49    checks!(cmd, ctx, [error, help, version, license]);
50    parse_ctx_and_run(cmd, ctx)
51}
52
53pub fn parse_ctx_and_run(cmd: Command, ctx: Context) -> action_result!() {
54    let l = {
55        let lf = cmd.l_flags.find("length").unwrap();
56        match ctx
57            .get_flag_value_of(&lf.name, &cmd)
58            .unwrap()
59            .get_int_unwrap()
60        {
61            x if x > 0 => x,
62            _ => lf.default_value.get_int_unwrap(),
63        }
64    } as usize;
65    let n = {
66        let nf = cmd.l_flags.find("number").unwrap();
67        match ctx
68            .get_flag_value_of(&nf.name, &cmd)
69            .unwrap()
70            .get_int_unwrap()
71        {
72            x if x > 0 => x,
73            _ => nf.default_value.get_int_unwrap(),
74        }
75    } as usize;
76    let include_str = match ctx
77        .get_flag_value_of("custom", &cmd)
78        .unwrap()
79        .get_string_value()
80    {
81        x if x.is_empty() => {
82            let include = ctx
83                .get_flag_value_of("include", &cmd)
84                .unwrap()
85                .get_string_value();
86            if include.contains('d') {
87                String::from(pwgen::str_list::get_alphabets())
88                    + pwgen::str_list::get_numbers()
89                    + pwgen::str_list::get_symbols()
90            } else {
91                let mut str = String::new();
92                if include.contains('a') {
93                    str += pwgen::str_list::get_alphabets();
94                }
95                if include.contains('n') {
96                    str += pwgen::str_list::get_numbers();
97                }
98                if include.contains('s') {
99                    str += pwgen::str_list::get_symbols();
100                }
101                str
102            }
103        }
104        x => x,
105    };
106
107    let include_chars: Vec<char> = match ctx.get_inputted_local_flag_value_of("exclude") {
108        None | Some(FlagValue::None) => include_str.chars().collect(),
109        Some(FlagValue::String(val)) if val.is_empty() => include_str.chars().collect(),
110        Some(ex) => {
111            let ex = ex.get_string_value();
112            include_str.chars().filter(|c| !ex.contains(*c)).collect()
113        }
114    };
115
116    if include_chars.is_empty() {
117        println!("No char can use in password!\r\n");
118        output_help!(&cmd, &ctx);
119        return done!();
120    }
121
122    let password_list = pwgen::pwgen(l, n, &include_chars);
123
124    println!("---generated passwords begin---");
125    for password in password_list {
126        println!("{password}");
127    }
128    println!("---generated passwords end---");
129
130    done!()
131}