sym_lang/
command.rs

1use std::env;
2use std::process;
3
4use crate::{error::SymError, utils};
5
6enum Command {
7    Help,
8    Run(String),
9    Version,
10}
11
12pub struct Commands {
13    command: Command,
14}
15
16impl Commands {
17    pub fn new() -> Result<Self, SymError> {
18        let args: Vec<String> = env::args().collect();
19
20        let command = if args.len() == 3 && args[1] == "run" {
21            Ok(Command::Run(args[2].clone()))
22        } else if args.len() == 2 {
23            match args[1].as_str() {
24                "help" => Ok(Command::Help),
25                "version" => Ok(Command::Version),
26                "run" => Err(SymError::NotEnoughArguments(
27                    "File path not found".to_string(),
28                )),
29                cmd => Err(SymError::UnknownCommand(cmd.to_string())),
30            }
31        } else if args.len() < 3 {
32            Err(SymError::NotEnoughArguments(args.len().to_string()))
33        } else {
34            Err(SymError::ManyArguments)
35        };
36
37        Ok(Self { command: command? })
38    }
39
40    pub fn run(self) -> Option<Vec<String>> {
41        match self.command {
42            Command::Run(file_name) => utils::read_lines(&file_name),
43            Command::Help => {
44                Self::help();
45                None
46            }
47            Command::Version => {
48                Self::version();
49                None
50            }
51        }
52    }
53
54    fn help() {
55        println!(
56            "Sym Lang's runner\n\nUsage: sym [COMMAND]\n\nCommands:\n  run [FILE PATH]    run a code\n  help               seable infomations for help\n  version            seable sym's version"
57        );
58        process::exit(0);
59    }
60
61    fn version() {
62        println!("sym {}", env!("CARGO_PKG_VERSION"));
63        process::exit(0);
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    /*
70    use super::*;
71    use std::env;
72
73    fn set_args(args: Vec<&str>) {
74        unsafe {
75            env::set_var("CARGO_PKG_VERSION", "0.1.0");
76            let args_string = args.join(" ");
77            //let args_vec: Vec<String> = args.iter().map(|s| s.to_string()).collect();
78            env::set_var("ARGS", args_string);
79            env::set_current_dir(env::current_dir().unwrap()).unwrap();
80        }
81    }
82
83    #[test]
84    fn test_run_command() {
85        let args = vec!["sym", "run", "test_file.sym"];
86        set_args(args);
87
88        let cmd = Commands::new();
89        assert!(matches!(cmd.command, Command::Run(file) if file == "test_file.sym"))
90    }
91
92    #[test]
93    fn test_help_command() {
94        let args = vec!["sym", "help"];
95        set_args(args);
96
97        let cmd = Commands::new();
98        assert!(matches!(cmd.command, Command::Help))
99    }
100
101    #[test]
102    fn test_version_command() {
103        let args = vec!["sym", "version"];
104        set_args(args);
105
106        let cmd = Commands::new();
107        assert!(matches!(cmd.command, Command::Version));
108    }
109
110    #[test]
111    fn test_no_args_error() {
112        let args = vec!["sym"];
113        set_args(args);
114
115        let cmd = Commands::new();
116        assert!(matches!(cmd.command, Command::Unknown));
117    }
118
119    #[test]
120    fn test_unknown_command_error() {
121        let args = vec!["sym", "hoge"];
122        set_args(args);
123
124        let cmd = Commands::new();
125        assert!(matches!(cmd.command, Command::Unknown));
126    }
127    */
128}