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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
pub mod color; pub type Action = fn(Vec<String>); pub struct Command { pub name: String, pub usage: String, pub action: Action, } pub struct App { pub name: String, pub display_name: String, pub usage: String, pub version: String, pub commands: Vec<Command>, } impl App { pub fn new() -> Self { Self { name: "".to_string(), display_name: "".to_string(), usage: "".to_string(), version: "".to_string(), commands: Vec::<Command>::new(), } } pub fn run(&self, args: Vec<String>) { match args.len() { 1 => { self.help(); std::process::exit(1); } _ => (), } let (cmd_v, args_v) = args[1..].split_at(1); let cmd = match cmd_v.first() { Some(c) => c, None => { self.help(); std::process::exit(1); } }; match (cmd.len(), args_v.len()) { (0, _) | (_, 0) => { self.help(); std::process::exit(1); } _ => (), } match self.select_command(&cmd) { Some(command) => (command.action)(args_v.to_vec()), None => self.help(), } } fn help(&self) { match self.display_name.len() { 0 => println!("Name:\n {}\n", self.name), _ => println!("Name:\n {}\n", self.display_name), } println!("Usage:\n {}\n", self.usage); println!("Version:\n {}\n", self.version); println!("Commands:"); for c in &self.commands { println!(" {} {} [arg]", self.name, c.name) } } fn select_command(&self, cmd: &String) -> Option<&Command> { (&self.commands) .into_iter() .find(|command| &command.name == cmd) } } #[cfg(test)] mod tests { use super::{App, Command}; #[test] fn app_test() { let c = Command { name: "hello".to_string(), usage: "test hello user".to_string(), action: |v: Vec<String>| println!("Hello, {:?}", v), }; let mut app = App::new(); app.name = "test".to_string(); app.usage = "test [command] [arg]".to_string(); app.version = "0.0.1".to_string(); app.commands = vec![c]; app.run(vec![ "test".to_string(), "hello".to_string(), "arg1".to_string(), "arg2".to_string(), "arg3".to_string(), "arg4".to_string(), ]); assert_eq!(app.name, "test".to_string()); assert_eq!(app.usage, "test [command] [arg]".to_string()); assert_eq!(app.version, "0.0.1".to_string()); } }