shell/
config.rs

1use std::env;
2use std::ffi::OsString;
3
4pub struct Config {
5    pub command: Option<String>,
6    pub script: Option<String>,
7    pub args: Vec<String>,
8}
9
10pub const VERSION_STRING: &str = env!("VERSION_STRING");
11
12const HELP: &str = r#"sl-sh - Simple Lisp Shell
13Start the sl-sh shell.
14
15USAGE:
16    sl-sh [FLAGS] [OPTIONS] [args]
17
18FLAGS:
19    -v, --version  Print the version, platform and revision of sl-sh then exit.
20    -h, --help     Print help (this) and exit.
21
22OPTIONS:
23    -c             Command to run instead of entering the REPL.
24
25ARGS:
26    <args>...      Script to run with arguments."#;
27
28fn help(_name: &str) {
29    println!("{}", HELP);
30}
31
32fn version() {
33    println!("{}", VERSION_STRING);
34}
35
36fn get_arg(exe_name: &str, args: &mut Vec<OsString>) -> Option<String> {
37    if let Some(argument) = args.pop() {
38        if let Ok(arg) = argument.into_string() {
39            return Some(arg);
40        }
41    }
42    help(exe_name);
43    None
44}
45
46pub fn get_config() -> Option<Config> {
47    let mut command: Option<String> = None;
48    let mut script: Option<String> = None;
49    let mut command_args: Vec<String> = Vec::new();
50
51    let mut args: Vec<OsString> = env::args_os().collect();
52
53    args.reverse();
54    let exe_name = get_arg("unknown", &mut args)?; // Pop off the executable name.
55
56    while !args.is_empty() {
57        if let Some(argument) = args.pop() {
58            if let Ok(arg) = argument.into_string() {
59                match &arg[..] {
60                    "-c" => {
61                        if command.is_some() {
62                            help(&exe_name);
63                            return None;
64                        }
65                        command = Some(get_arg(&exe_name, &mut args)?);
66                    }
67                    "-v" | "--version" if command.is_none() => {
68                        version();
69                        return None;
70                    }
71                    "-h" | "--help" if command.is_none() => {
72                        help(&exe_name);
73                        return None;
74                    }
75                    _ => {
76                        if command.is_none() && script.is_none() {
77                            script = Some(arg);
78                        } else {
79                            command_args.push(arg);
80                        }
81                    }
82                }
83            } else {
84                help(&exe_name);
85                return None;
86            }
87        }
88    }
89    Some(Config {
90        command,
91        script,
92        args: command_args,
93    })
94}