aboutsummaryrefslogtreecommitdiff
path: root/src/command.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/command.rs')
-rw-r--r--src/command.rs98
1 files changed, 18 insertions, 80 deletions
diff --git a/src/command.rs b/src/command.rs
index 40801e7..e4c099e 100644
--- a/src/command.rs
+++ b/src/command.rs
@@ -122,6 +122,7 @@ pub enum Command {
122#[derive(Debug)] 122#[derive(Debug)]
123pub enum CommandLineError { 123pub enum CommandLineError {
124 InvalidCommand(String), // command name 124 InvalidCommand(String), // command name
125 InvalidArg(u32), // position
125 NotEnoughArgs(String, u32), // command name, required no. of args 126 NotEnoughArgs(String, u32), // command name, required no. of args
126} 127}
127 128
@@ -131,6 +132,7 @@ impl fmt::Display for CommandLineError {
131 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 132 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
132 match self { 133 match self {
133 CommandLineError::InvalidCommand(s) => write!(f, "Invalid command: `{}`", s), 134 CommandLineError::InvalidCommand(s) => write!(f, "Invalid command: `{}`", s),
135 CommandLineError::InvalidArg(p) => write!(f, "Invalid argument at position {}", p),
134 CommandLineError::NotEnoughArgs(s, n) => { 136 CommandLineError::NotEnoughArgs(s, n) => {
135 write!(f, "Command `{}` requires atleast {} argument(s)!", s, n) 137 write!(f, "Command `{}` requires atleast {} argument(s)!", s, n)
136 } 138 }
@@ -148,9 +150,23 @@ impl Command {
148 } 150 }
149 151
150 let first = strings.first().unwrap().to_string(); 152 let first = strings.first().unwrap().to_string();
151 let args: Vec<String> = strings.iter_mut().skip(1).map(|s| s.to_string()).collect(); 153 let mut args: Vec<String> = strings.iter_mut().skip(1).map(|s| s.to_string()).collect();
152 let mut _add = |auto: bool, first: String| { 154 let mut _add = |auto: bool, first: String| {
153 return parse_add(first, args.clone(), auto); 155 if args.is_empty() {
156 return Err(CommandLineError::NotEnoughArgs(first, 1));
157 }
158 let goal = args
159 .get(1)
160 .map(|x| {
161 x.parse::<u32>()
162 .map_err(|_| CommandLineError::InvalidArg(2))
163 })
164 .transpose()?;
165 return Ok(Command::Add(
166 args.get_mut(0).unwrap().to_string(),
167 goal,
168 auto,
169 ));
154 }; 170 };
155 171
156 match first.as_ref() { 172 match first.as_ref() {
@@ -189,81 +205,3 @@ impl Command {
189 } 205 }
190 } 206 }
191} 207}
192
193fn parse_add(verb: String, args: Vec<String>, auto: bool) -> Result<Command> {
194 if args.is_empty() {
195 return Err(CommandLineError::NotEnoughArgs(verb, 1));
196 }
197
198 let mut pos = 1;
199 let mut acc = "".to_owned();
200 let mut new_goal: Option<u32> = None;
201 for s1 in args {
202 if pos == 1 {
203 acc.push_str(&s1);
204 } else {
205 if let Ok(n) = s1.parse::<u32>() {
206 new_goal = Some(n);
207 } else {
208 acc.push(' ');
209 acc.push_str(&s1);
210 }
211 }
212 pos = pos + 1;
213 }
214
215 return Ok(Command::Add(acc, new_goal, auto));
216}
217
218#[cfg(test)]
219mod tests {
220 use super::*;
221
222 #[test]
223 fn parse_add_command_with_goal() {
224 let command: Vec<String> = "eat healthy 3"
225 .trim()
226 .split(' ')
227 .into_iter()
228 .map(|s| s.to_string())
229 .collect();
230
231 let verb = "add".to_owned();
232 let auto = false;
233
234 let result = parse_add(verb, command, auto);
235
236 match result.unwrap() {
237 Command::Add(name, goal, a) => {
238 assert_eq!(name, "eat healthy".to_owned());
239 assert_eq!(goal.unwrap(), 3);
240 assert_eq!(a, auto);
241 }
242 _ => panic!(),
243 }
244 }
245
246 #[test]
247 fn parse_add_command_without_goal() {
248 let command: Vec<String> = "eat healthy"
249 .trim()
250 .split(' ')
251 .into_iter()
252 .map(|s| s.to_string())
253 .collect();
254
255 let verb = "add".to_owned();
256 let auto = false;
257
258 let result = parse_add(verb, command, auto);
259
260 match result.unwrap() {
261 Command::Add(name, goal, a) => {
262 assert_eq!(name, "eat healthy".to_owned());
263 assert!(goal.is_none());
264 assert_eq!(a, auto);
265 }
266 _ => panic!(),
267 }
268 }
269}