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