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`: 用户命令
parse(args: Vec<String>) -> UserCommand16 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命令
parse(args: Vec<String>) -> PasswdCommand81 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`: 组命令
parse(args: Vec<String>) -> GroupCommand101 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]
invalid_handle()135 fn invalid_handle() {
136 ErrorHandler::error_handle("Invalid option".to_string(), ExitStatus::InvalidCmdSyntax);
137 }
138