aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/command.rs98
1 files changed, 80 insertions, 18 deletions
diff --git a/src/command.rs b/src/command.rs
index 38d48e9..a893430 100644
--- a/src/command.rs
+++ b/src/command.rs
@@ -122,7 +122,6 @@ 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
126 NotEnoughArgs(String, u32), // command name, required no. of args 125 NotEnoughArgs(String, u32), // command name, required no. of args
127} 126}
128 127
@@ -132,7 +131,6 @@ impl fmt::Display for CommandLineError {
132 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 131 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
133 match self { 132 match self {
134 CommandLineError::InvalidCommand(s) => write!(f, "Invalid command: `{}`", s), 133 CommandLineError::InvalidCommand(s) => write!(f, "Invalid command: `{}`", s),
135 CommandLineError::InvalidArg(p) => write!(f, "Invalid argument at position {}", p),
136 CommandLineError::NotEnoughArgs(s, n) => { 134 CommandLineError::NotEnoughArgs(s, n) => {
137 write!(f, "Command `{}` requires atleast {} argument(s)!", s, n) 135 write!(f, "Command `{}` requires atleast {} argument(s)!", s, n)
138 } 136 }
@@ -150,23 +148,9 @@ impl Command {
150 } 148 }
151 149
152 let first = strings.first().unwrap().to_string(); 150 let first = strings.first().unwrap().to_string();
153 let mut args: Vec<String> = strings.iter_mut().skip(1).map(|s| s.to_string()).collect(); 151 let args: Vec<String> = strings.iter_mut().skip(1).map(|s| s.to_string()).collect();
154 let mut _add = |auto: bool, first: String| { 152 let mut _add = |auto: bool, first: String| {
155 if args.is_empty() { 153 return parse_add(first, args.clone(), auto);
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 ));
170 }; 154 };
171 155
172 match first.as_ref() { 156 match first.as_ref() {
@@ -205,3 +189,81 @@ impl Command {
205 } 189 }
206 } 190 }
207} 191}
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}