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)?; 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}