1 use super::cmd::{CmdOption, GroupCommand, PasswdCommand, UserCommand}; 2 use crate::error::error::{ErrorHandler, ExitStatus}; 3 use std::collections::HashMap; 4 5 /// 用户命令(useradd/userdel/usermod)解析器 6 pub struct UserParser; 7 8 impl UserParser { 9 /// **解析用户命令** 10 /// 11 /// ## 参数 12 /// - `args`: 用户命令参数 13 /// 14 /// ## 返回 15 /// - `UserCommand`: 用户命令 16 pub fn parse(args: Vec<String>) -> UserCommand { 17 let username = args.last().unwrap().clone(); 18 let args = &args[1..args.len() - 1]; 19 let mut options = HashMap::new(); 20 21 let mut idx = 0; 22 loop { 23 if idx >= args.len() { 24 break; 25 } 26 let option: CmdOption = args[idx].clone().into(); 27 match option { 28 CmdOption::Invalid => invalid_handle(), 29 CmdOption::Remove => { 30 if idx + 1 < args.len() { 31 let op: &str = option.clone().into(); 32 ErrorHandler::error_handle( 33 format!("Invalid arg {} of option: {}", args[idx + 1], op), 34 ExitStatus::InvalidCmdSyntax, 35 ) 36 } 37 options.insert(option, "".to_string()); 38 } 39 CmdOption::Append => { 40 if idx + 1 >= args.len() || idx + 2 >= args.len() || args[idx + 1] != "-G" { 41 ErrorHandler::error_handle( 42 "Invalid option: -a -G <group1,group2,...>".to_string(), 43 ExitStatus::InvalidCmdSyntax, 44 ); 45 } 46 idx += 2; 47 let groups = &args[idx]; 48 options.insert(option, groups.clone()); 49 } 50 _ => { 51 if idx + 1 >= args.len() { 52 let op: &str = option.clone().into(); 53 ErrorHandler::error_handle( 54 format!("Invalid arg of option: {}", op), 55 ExitStatus::InvalidCmdSyntax, 56 ); 57 } 58 idx += 1; 59 let value = args[idx].clone(); 60 options.insert(option, value); 61 } 62 } 63 idx += 1; 64 } 65 66 UserCommand { username, options } 67 } 68 } 69 70 /// passwd命令解析器 71 pub struct PasswdParser; 72 73 impl PasswdParser { 74 /// **解析passwd命令** 75 /// 76 /// ## 参数 77 /// - `args`: passwd命令参数 78 /// 79 /// ## 返回 80 /// - `PasswdCommand`: passwd命令 81 pub fn parse(args: Vec<String>) -> PasswdCommand { 82 let mut username = None; 83 if args.len() > 1 { 84 username = Some(args.last().unwrap().clone()); 85 } 86 PasswdCommand { username } 87 } 88 } 89 90 /// 组命令(groupadd/groupdel/groupmod)解析器 91 pub struct GroupParser; 92 93 impl GroupParser { 94 /// **解析组命令** 95 /// 96 /// ## 参数 97 /// - `args`: 组命令参数 98 /// 99 /// ## 返回 100 /// - `GroupCommand`: 组命令 101 pub fn parse(args: Vec<String>) -> GroupCommand { 102 let groupname = args.last().unwrap().clone(); 103 let args = &args[1..args.len() - 1]; 104 let mut options = HashMap::new(); 105 106 let mut idx = 0; 107 loop { 108 if idx >= args.len() { 109 break; 110 } 111 let option: CmdOption = args[idx].clone().into(); 112 match option { 113 CmdOption::Invalid => invalid_handle(), 114 _ => { 115 if idx + 1 >= args.len() { 116 let op: &str = option.clone().into(); 117 ErrorHandler::error_handle( 118 format!("Invalid arg of option: {}", op), 119 ExitStatus::InvalidCmdSyntax, 120 ); 121 } 122 idx += 1; 123 let value = args[idx].clone(); 124 options.insert(option, value); 125 } 126 } 127 idx += 1; 128 } 129 130 GroupCommand { groupname, options } 131 } 132 } 133 134 #[inline] 135 fn invalid_handle() { 136 ErrorHandler::error_handle("Invalid option".to_string(), ExitStatus::InvalidCmdSyntax); 137 } 138