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