commands/
commands.rs

1use ltnt::Parsable;
2
3ltnt::ltnt!(
4    // A set of commands that, when used itself as a command, accepts the arguments of 'Root'
5    pub enum Manager in ManagerArgs {
6        // Basic command named 'help', can be a full path to the type. If no
7        // command is passed, this is the default
8        ~Help = Help,
9
10        // Nested command called with 'ls'
11        Ls = Ls,
12
13        // Nested command called with `dev` (*not* `info`)
14        Info = Info as "dev",
15    };
16
17    // A set of arguments being used as the arguments for 'Manager' (but can be used anywhere)
18    pub struct ManagerArgs {
19        // A required argument with a short form
20        pub name('n'): String,
21
22        // An argument with a built-in default value (`false`), that therefore doesn't need to be passed
23        pub verbose: bool,
24    };
25
26    // A set of arguments that's being used in 'Manager' as a command
27    struct Help {
28        // An argument with a given default value, that therefore doesn't need to be passed
29        pub courteous: bool = true,
30    };
31
32    // A set of arguments that's being used in 'Manager' as a command
33    struct Ls {
34        pub all('a'): bool = true,
35
36        // An optional argument (is really `Option<String>`, defaults to `None`)
37        pub filter('f') ?: String,
38    };
39
40    #[derive(Debug)]
41    pub struct Info {
42        // An optional argument set with `--type`
43        pub device_type as "type" ?: Vec<String>,
44    };
45);
46
47#[rustfmt::skip]
48const DEVICES: &[(&str, &str)] = &[
49    (
50        "Omega Keyboard",
51        "keys: 450, latency: 0.73ms, color: sRGB",
52    ),
53    (
54        "Quik Mouse 3.5",
55        "dpi: 1000000, latency: 0.01ms, color: RGB",
56    ),
57    (
58        "SoundBlasters",
59        "volume: 150%, latency: 0.58ms, color: none",
60    ),
61    (
62        "UltraRes Retina Display",
63        "brightness: 75%, latency: 2.3ms, color: sRGB",
64    ),
65];
66
67fn main() {
68    let (cmd, args, rest) = Manager::parse().unwrap();
69
70    if args.verbose {
71        println!("Greetings, my dear friend, {}! Welcome!", args.name);
72    } else {
73        println!("Hello, {}!", args.name);
74    }
75
76    match cmd {
77        Manager::Help(help) => {
78            if help.courteous {
79                println!("Please read the manual online.");
80            } else {
81                panic!("Read the docs, doofus.");
82            }
83        }
84        Manager::Ls(ls) => {
85            let list = if ls.all { DEVICES } else { &DEVICES[2..] };
86
87            if let Some(filter) = ls.filter {
88                for (item, _) in list {
89                    if item.contains(&filter) {
90                        println!("{item}");
91                    }
92                }
93            } else {
94                for (item, _) in list {
95                    println!("{item}");
96                }
97            }
98        }
99
100        Manager::Info(info) => {
101            if let Some(types) = info.device_type {
102                if types.contains(&"keyboard".into()) {
103                    let (device, description) = DEVICES[0];
104                    println!("{device} : {description}");
105                }
106
107                if types.contains(&"mouse".into()) {
108                    let (device, description) = DEVICES[1];
109                    println!("{device} : {description}");
110                }
111
112                if types.contains(&"speaker".into()) || types.contains(&"headphones".into()) {
113                    let (device, description) = DEVICES[2];
114                    println!("{device} : {description}");
115                }
116
117                if types.contains(&"display".into()) || types.contains(&"monitor".into()) {
118                    let (device, description) = DEVICES[3];
119                    println!("{device} : {description}");
120                }
121            } else {
122                for (device, description) in DEVICES {
123                    println!("{device} : {description}");
124                }
125            }
126        }
127    }
128
129    for item in rest {
130        println!("We don't support or provide {item}");
131    }
132}