xref: /DragonOS/user/apps/user-manage/src/parser/parser.rs (revision af097f9f4b317337fe74aaa5070c34a14b8635fd)
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