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
#![allow(dead_code)]
use std::collections::BTreeMap;
use std::env;

#[derive(Clone)]
pub struct Flags {
    pub(crate) cmds: Vec<Cmd>,
    pub(crate) args: BTreeMap<String, String>,
}
#[derive(Clone)]
pub struct Cmd {
    pub(crate) cmd: String,
    pub(crate) args: BTreeMap<String, String>,
}

impl Flags {
    fn new() -> Self {
        Flags {
            cmds: vec![],
            args: BTreeMap::new(),
        }
    }
    pub fn get_cmd(&self, cmd: &str) -> Option<Cmd> {
        for c in self.cmds.iter() {
            if c.cmd.eq(cmd) {
                return Some(c.clone());
            }
        }
        None
    }
    pub fn add_flag<S: ToString>(mut self, key: S, value: S) -> Self {
        self.args.insert(key.to_string(), value.to_string());
        self
    }
    pub(crate) fn parse_args() -> Self {
        let args: Vec<String> = env::args().collect();
        let mut flags = Self::new();
        let mut i = 1;
        while i < args.len() {
            if &args[i][..1] == "-" {
                let value = args.get(i + 1);
                if value.is_none() {
                    i += 1;
                    continue;
                }
                let key = args[i].clone();
                let key = key
                    .trim_start_matches(|c: char| c == '-')
                    .to_string();
                let value = value.unwrap().clone();
                if let Some(cmd) = flags.cmds.last_mut() {
                    cmd.args.insert(key, value);
                } else {
                    flags.args.insert(key, value);
                }
                i += 2;
            } else {
                let cmd = Cmd::new(args[i].clone());
                flags.cmds.push(cmd);
                i += 1;
            }
        }
        return flags;
    }
}
impl Cmd {
    pub fn new(cmd: String) -> Self {
        Cmd {
            cmd,
            args: BTreeMap::new(),
        }
    }
    pub fn add_flag<S: ToString>(mut self, key: S, value: S) -> Self {
        self.args.insert(key.to_string(), value.to_string());
        self
    }
}