1use crate::args::ArgumentList;
2use crate::command::Command;
3use crate::option::OptionList;
4use crate::Argument;
5use std::fmt::Display;
6use std::slice::Iter;
7use std::str::FromStr;
8
9#[derive(Debug, Clone)]
12pub struct ParseResult {
13 command: Command,
14 options: OptionList,
15 args: ArgumentList,
16}
17
18impl ParseResult {
19 pub fn new(command: Command, options: OptionList, args: ArgumentList) -> Self {
21 ParseResult {
22 command,
23 options,
24 args,
25 }
26 }
27
28 #[doc(hidden)]
30 pub fn executing_command(&self) -> &Command {
31 &self.command
32 }
33
34 pub fn command_name(&self) -> &str {
36 self.command.get_name()
37 }
38
39 pub fn command_version(&self) -> Option<&str> {
41 self.command.get_version()
42 }
43
44 pub fn command_help(&self) -> Option<&str> {
46 self.command.get_help()
47 }
48
49 pub fn command_usage(&self) -> Option<&str> {
51 self.command.get_usage()
52 }
53
54 pub fn options(&self) -> &OptionList {
56 &self.options
57 }
58
59 pub fn arg(&self) -> Option<&Argument> {
61 if self.args.len() == 1 {
62 Some(&self.args[0])
63 } else {
64 None
65 }
66 }
67
68 pub fn args(&self) -> &ArgumentList {
70 &self.args
71 }
72
73 pub fn value_of(&self, arg_name: &str) -> Option<&str> {
75 self.args
76 .get(arg_name)
77 .map(|arg| arg.get_values())
78 .filter(|values| values.len() == 1)
79 .map(|values| values[0].as_str())
80 }
81
82 pub fn values_of(&self, arg_name: &str) -> Option<Values<'_>> {
84 if let Some(arg) = self.args.get(arg_name) {
85 Some(Values {
86 values: arg.get_values(),
87 })
88 } else {
89 None
90 }
91 }
92
93 pub fn value_of_option(&self, option_name: &str) -> Option<&str> {
95 self.options
96 .get(option_name)
97 .map(|opt| opt.get_arg())
98 .flatten()
99 .map(|arg| arg.get_values())
100 .filter(|values| values.len() == 1)
101 .map(|values| values[0].as_str())
102 }
103
104 pub fn values_of_option(&self, option_name: &str) -> Option<Values<'_>> {
106 if let Some(option) = self.options.get(option_name) {
107 let arg = option.get_arg()?;
108 Some(Values {
109 values: arg.get_values(),
110 })
111 } else {
112 None
113 }
114 }
115
116 pub fn value_of_as<T>(&self, arg_name: &str) -> Option<T>
118 where
119 T: FromStr + 'static,
120 <T as FromStr>::Err: Display,
121 {
122 self.args().convert::<T>(arg_name).ok()
123 }
124
125 pub fn values_of_as<T>(&self, arg_name: &str) -> Option<Vec<T>>
127 where
128 T: FromStr + 'static,
129 <T as FromStr>::Err: Display,
130 {
131 self.args().convert_all(arg_name).ok()
132 }
133
134 pub fn value_of_option_as<T>(&self, option_name: &str) -> Option<T>
136 where
137 T: FromStr + 'static,
138 <T as FromStr>::Err: Display,
139 {
140 self.options().convert::<T>(option_name).ok()
141 }
142
143 pub fn values_of_option_as<T>(&self, option_name: &str) -> Option<Vec<T>>
145 where
146 T: FromStr + 'static,
147 <T as FromStr>::Err: Display,
148 {
149 self.options().convert_all(option_name).ok()
150 }
151}
152
153#[derive(Debug, Clone)]
155pub struct Values<'a> {
156 values: &'a [String],
157}
158
159impl<'a> Values<'a> {
160 pub fn iter(&self) -> Iter<'_, String> {
162 self.values.iter()
163 }
164
165 #[inline]
167 pub fn len(&self) -> usize {
168 self.values.len()
169 }
170
171 #[inline]
172 pub fn is_empty(&self) -> bool {
173 self.values.is_empty()
174 }
175
176 #[inline]
178 pub fn contains<S: AsRef<str>>(&self, value: S) -> bool {
179 self.values.iter().any(|s| s == value.as_ref())
180 }
181
182 #[inline]
184 pub fn inner(&self) -> &'a [String] {
185 self.values
186 }
187}
188
189impl<'a> IntoIterator for Values<'a> {
190 type Item = &'a String;
191 type IntoIter = Iter<'a, String>;
192
193 fn into_iter(self) -> Self::IntoIter {
194 self.values.into_iter()
195 }
196}
197
198impl<'a> IntoIterator for &'a Values<'a> {
199 type Item = &'a String;
200 type IntoIter = Iter<'a, String>;
201
202 fn into_iter(self) -> Self::IntoIter {
203 self.values.into_iter()
204 }
205}
206
207#[cfg(test)]
208mod tests {
209 use super::*;
210 use crate::validator::validate_type;
211 use crate::{split_into_args, CommandOption, Context, ErrorKind, Parser};
212
213 fn parse_with(value: &str, command: Command) -> crate::Result<ParseResult> {
214 let context = Context::new(command);
215 Parser::new(&context).parse(split_into_args(value))
216 }
217
218 #[test]
219 fn parse_result_command_test() {
220 let command = Command::new("MyApp")
221 .arg(Argument::one_or_more("values"))
222 .option(
223 CommandOption::new("repeat").alias("r").arg(
224 Argument::with_name("times")
225 .validator(validate_type::<u64>())
226 .default(1),
227 ),
228 )
229 .option(
230 CommandOption::new("color")
231 .alias("c")
232 .arg(Argument::with_name("color").valid_values(&["red", "blue", "green"])),
233 );
234
235 let result = parse_with("--repeat 2 -c red hello world!", command.clone()).unwrap();
236 assert!(result.options().contains("repeat"));
237 assert!(result.options().contains("r"));
238 assert!(result.options().contains("color"));
239 assert!(result.options().contains("c"));
240 assert_eq!(
241 result
242 .options()
243 .get("repeat")
244 .unwrap()
245 .get_arg()
246 .unwrap()
247 .convert::<u64>()
248 .ok(),
249 Some(2)
250 );
251 assert!(result
252 .options()
253 .get("color")
254 .unwrap()
255 .get_arg()
256 .unwrap()
257 .contains("red"));
258 assert_eq!(result.arg().unwrap().get_values(), &["hello", "world!"]);
259
260 assert!(parse_with("\" \"", command.clone())
262 .unwrap()
263 .arg()
264 .unwrap()
265 .contains(" "));
266
267 assert!(parse_with("Hola Mundo!", command.clone()).is_ok());
269 assert!(parse_with("--repeat 10 Hola Mundo!", command.clone()).is_ok());
270 assert!(parse_with("--color green Hola Mundo!", command.clone()).is_ok());
271 assert!(parse_with("-c blue -- Hola Mundo!", command.clone()).is_ok());
272 assert!(parse_with("\" \"", command.clone()).is_ok());
273
274 assert!(parse_with("--repeat -2 Hola Mundo!", command.clone()).is_err());
276 assert!(parse_with("", command.clone()).is_err());
277 assert!(parse_with("--repeat 2 -c:red", command.clone()).is_err());
278 assert!(parse_with("-r a Hello World", command.clone()).is_err());
279 assert!(parse_with("-c yellow Hello World", command.clone()).is_err());
280 }
281
282 #[test]
283 fn parse_result_subcommand_test() {
284 let command = Command::new("MyApp")
285 .subcommand(Command::new("version"))
286 .subcommand(
287 Command::new("set")
288 .arg(Argument::one_or_more("value"))
289 .option(CommandOption::new("repeat").arg(Argument::with_name("count"))),
290 )
291 .subcommand(Command::new("get"));
292
293 let result = parse_with("set --repeat 1 1 2 3 4", command.clone()).unwrap();
294 assert_eq!(result.executing_command().get_name(), "set");
295 assert!(result
296 .options()
297 .get("repeat")
298 .unwrap()
299 .get_arg()
300 .unwrap()
301 .contains("1"));
302 assert_eq!(
303 result.arg().unwrap().get_values(),
304 &[
305 "1".to_owned(),
306 "2".to_owned(),
307 "3".to_owned(),
308 "4".to_owned()
309 ]
310 );
311
312 assert!(parse_with("version", command.clone()).is_ok());
314 assert!(parse_with("set 1 2 3", command.clone()).is_ok());
315 assert!(parse_with("get", command.clone()).is_ok());
316 assert!(parse_with("", command.clone()).is_ok());
317
318 assert!(parse_with("Hello", command.clone()).is_err());
320 assert!(parse_with("version hello", command.clone()).is_err());
321 assert!(parse_with("version set 1 2 3", command.clone()).is_err());
322 assert!(parse_with("version hello", command.clone()).is_err());
323 }
324
325 #[test]
326 fn parse_result_required_option_test() {
327 let command = Command::new("MyApp")
328 .option(CommandOption::new("enable"))
329 .option(
330 CommandOption::new("times")
331 .alias("t")
332 .required(true)
333 .arg(Argument::with_name("times").validator(validate_type::<u64>())),
334 )
335 .arg(Argument::zero_or_more("values"));
336
337 let result = parse_with("--times 1 -- one two three", command.clone()).unwrap();
338 assert!(result.options().contains("times"));
339 assert!(result
340 .options()
341 .get("times")
342 .unwrap()
343 .get_arg()
344 .unwrap()
345 .contains("1"));
346 assert!(result.arg().unwrap().contains("one"));
347 assert!(result.arg().unwrap().contains("two"));
348 assert!(result.arg().unwrap().contains("three"));
349
350 assert!(parse_with("--times 1", command.clone()).is_ok());
352 assert!(parse_with("--times 1 1 2 3", command.clone()).is_ok());
353 assert!(parse_with("--times 1 --enable", command.clone()).is_ok());
354
355 assert!(parse_with("--times 1 --enable false", command.clone()).is_ok());
358
359 assert!(parse_with("--times 1 --enable false --", command.clone()).is_err());
366
367 assert!(parse_with(" ", command.clone()).is_err());
368 assert!(parse_with("--times", command.clone()).is_err());
369 }
370
371 #[test]
372 fn parse_result_options_test() {
373 let command = Command::new("MyApp")
374 .option(CommandOption::new("hour").alias("h"))
375 .option(CommandOption::new("minute").alias("m"))
376 .option(CommandOption::new("second").alias("s"))
377 .option(
378 CommandOption::new("enable").arg(
379 Argument::with_name("value")
380 .validator(validate_type::<bool>())
381 .values_count(0..=1),
382 ),
383 );
384
385 let result = parse_with("--hour -m -s --enable false", command.clone()).unwrap();
386 assert_eq!(result.args().len(), 0);
387 assert!(result.options().contains("hour"));
388 assert!(result.options().contains("minute"));
389 assert!(result.options().contains("second"));
390 assert!(result
391 .options()
392 .get("enable")
393 .unwrap()
394 .get_arg()
395 .unwrap()
396 .contains("false"));
397 }
398
399 #[test]
400 fn parse_result_multiple_args_test() {
401 let command = Command::new("MyApp")
402 .arg(Argument::with_name("min").validator(validate_type::<i64>()))
403 .arg(Argument::with_name("max").validator(validate_type::<i64>()))
404 .option(
405 CommandOption::new("replace")
406 .alias("r")
407 .arg(Argument::with_name("from"))
408 .arg(Argument::with_name("to")),
409 );
410
411 let result = parse_with("--replace a A -- 2 10", command.clone()).unwrap();
412 assert!(result
413 .options()
414 .get("replace")
415 .unwrap()
416 .get_args()
417 .get("from")
418 .unwrap()
419 .contains("a"));
420 assert!(result
421 .options()
422 .get("replace")
423 .unwrap()
424 .get_args()
425 .get("to")
426 .unwrap()
427 .contains("A"));
428 assert_eq!(
429 result.args().get("min").unwrap().convert::<i64>().ok(),
430 Some(2)
431 );
432 assert_eq!(
433 result.args().get("max").unwrap().convert::<i64>().ok(),
434 Some(10)
435 );
436
437 assert!(parse_with("2 10", command.clone()).is_ok());
439
440 assert!(parse_with("--replace hello HELLO", command.clone()).is_err());
442 assert!(parse_with("25", command.clone()).is_err());
443 }
444
445 #[test]
446 fn parse_result_eoa_test() {
447 let command = Command::new("MyApp")
448 .arg(Argument::one_or_more("args"))
449 .option(CommandOption::new("A").alias("a"))
450 .option(CommandOption::new("B").alias("b"))
451 .option(CommandOption::new("C").alias("c"))
452 .option(
453 CommandOption::new("D")
454 .alias("d")
455 .arg(Argument::one_or_more("d")),
456 );
457
458 let result1 = parse_with("--A --B -- --C", command.clone()).unwrap();
459 assert_eq!(result1.options().len(), 2);
460 assert_eq!(result1.arg().unwrap().get_values().len(), 1);
461 assert!(result1.options().contains("A"));
462 assert!(result1.options().contains("B"));
463 assert!(result1.arg().unwrap().contains("--C"));
464
465 let result2 = parse_with("-- --A -b --C", command.clone()).unwrap();
466 assert_eq!(result2.options().len(), 0);
467 assert_eq!(result2.arg().unwrap().get_values().len(), 3);
468 assert!(result2.arg().unwrap().contains("--A"));
469 assert!(result2.arg().unwrap().contains("-b"));
470 assert!(result2.arg().unwrap().contains("--C"));
471
472 let result3 = parse_with("-- -- -a -b -c", command.clone()).unwrap();
473 assert_eq!(result3.options().len(), 0);
474 assert_eq!(result3.arg().unwrap().get_values().len(), 4);
475 assert!(result3.arg().unwrap().contains("--"));
476 assert!(result3.arg().unwrap().contains("-a"));
477 assert!(result3.arg().unwrap().contains("-b"));
478 assert!(result3.arg().unwrap().contains("-c"));
479
480 let result4 = parse_with("--D 1 2 3 -- hello world", command.clone()).unwrap();
481 assert_eq!(result4.options().len(), 1);
482 assert!(result4.options().get_arg("D").unwrap().contains("1"));
483 assert!(result4.options().get_arg("D").unwrap().contains("2"));
484 assert!(result4.options().get_arg("D").unwrap().contains("3"));
485 assert!(result4.arg().unwrap().contains("hello"));
486 assert!(result4.arg().unwrap().contains("world"));
487
488 let result5 = parse_with("1 2 3 -- hello world", command.clone());
489 assert!(result5.is_err());
490 }
491
492 #[test]
493 fn parse_result_variable_arg_count_test1() {
494 let command = Command::new("MyApp")
495 .arg(Argument::with_name("values").values_count(0..=3))
496 .option(
497 CommandOption::new("letters").arg(
498 Argument::with_name("letters")
499 .values_count(1..)
500 .validator(validate_type::<char>()),
501 ),
502 )
503 .option(
504 CommandOption::new("numbers").arg(
505 Argument::with_name("numbers")
506 .values_count(1..=2)
507 .validator(validate_type::<i64>()),
508 ),
509 );
510
511 let result = parse_with(
512 "--letters a b c d e --numbers 1 -- one two three",
513 command.clone(),
514 )
515 .unwrap();
516
517 assert_eq!(
518 result
519 .options()
520 .get("letters")
521 .unwrap()
522 .get_arg()
523 .unwrap()
524 .get_values()
525 .len(),
526 5
527 );
528 assert!(result
529 .options()
530 .get("letters")
531 .unwrap()
532 .get_arg()
533 .unwrap()
534 .contains("a"));
535 assert!(result
536 .options()
537 .get("letters")
538 .unwrap()
539 .get_arg()
540 .unwrap()
541 .contains("b"));
542 assert!(result
543 .options()
544 .get("letters")
545 .unwrap()
546 .get_arg()
547 .unwrap()
548 .contains("c"));
549 assert!(result
550 .options()
551 .get("letters")
552 .unwrap()
553 .get_arg()
554 .unwrap()
555 .contains("d"));
556 assert!(result
557 .options()
558 .get("letters")
559 .unwrap()
560 .get_arg()
561 .unwrap()
562 .contains("e"));
563 assert!(result
564 .options()
565 .get("numbers")
566 .unwrap()
567 .get_arg()
568 .unwrap()
569 .contains("1"));
570 assert!(result.arg().unwrap().contains("one"));
571 assert!(result.arg().unwrap().contains("two"));
572 assert!(result.arg().unwrap().contains("three"));
573
574 assert_eq!(
576 parse_with(
577 "--letters a b c d e --numbers 1 2 3 -- one two three",
578 command.clone()
579 )
580 .err()
581 .unwrap()
582 .kind(),
583 &ErrorKind::InvalidArgumentCount
584 );
585 }
586
587 #[test]
588 fn parse_result_error_kind_test() {
589 let command = Command::new("MyApp")
590 .arg(Argument::with_name("values").values_count(0..5))
591 .subcommand(Command::new("version"))
592 .option(
593 CommandOption::new("range")
594 .alias("r")
595 .arg(Argument::with_name("min").validator(validate_type::<i64>()))
596 .arg(Argument::with_name("max").validator(validate_type::<i64>())),
597 )
598 .option(CommandOption::new("A").alias("a"))
599 .option(CommandOption::new("B").alias("b"))
600 .subcommand(
601 Command::new("read").option(
602 CommandOption::new("mode")
603 .required(true)
604 .arg(Argument::with_name("mode").valid_values(&["low", "mid", "high"])),
605 ),
606 )
607 .subcommand(
608 Command::new("data")
609 .subcommand(Command::new("set").arg(Argument::with_name("value")))
610 .subcommand(Command::new("get")),
611 );
612
613 let err_kind = move |value: &str| -> ErrorKind {
614 parse_with(value, command.clone())
615 .err()
616 .unwrap_or_else(|| panic!("{}", value))
617 .kind()
618 .clone()
619 };
620
621 assert!(matches!(
622 err_kind("version 1 2 3"),
623 ErrorKind::InvalidArgumentCount
624 ));
625 assert!(matches!(
626 err_kind("-- 1 2 3 4 5"),
627 ErrorKind::InvalidArgumentCount
628 ));
629 assert!(matches!(
630 err_kind("--range 0"),
631 ErrorKind::InvalidArgumentCount
632 ));
633 assert!(matches!(
634 err_kind("--range 1 2 3 -- "),
635 ErrorKind::InvalidArgumentCount
636 ));
637 assert!(matches!(err_kind("-r=0=1"), ErrorKind::InvalidExpression));
638 assert!(
639 matches!(err_kind("--range 10 b"), ErrorKind::InvalidArgument(arg) if arg == "max")
640 );
641 assert!(matches!(err_kind("--C"), ErrorKind::UnexpectedOption(o) if o == "--C"));
642 assert!(matches!(err_kind("data write"), ErrorKind::UnexpectedCommand(x) if x == "write"));
643 assert!(matches!(err_kind("read"), ErrorKind::MissingOption(x) if x == "mode"));
644 assert!(
645 matches!(err_kind("read --mode lo"), ErrorKind::InvalidArgument(arg) if arg == "mode")
646 );
647 assert!(matches!(
648 err_kind("read --mode low mid"),
649 ErrorKind::InvalidArgumentCount
650 ));
651 assert!(matches!(err_kind("data clear"), ErrorKind::UnexpectedCommand(x) if x == "clear"));
652 assert!(matches!(
653 err_kind("data get 0"),
654 ErrorKind::InvalidArgumentCount
655 ));
656 assert!(matches!(
657 err_kind("data set \"Hello World\" Bye"),
658 ErrorKind::InvalidArgumentCount
659 ));
660 }
661
662 #[test]
663 fn parse_result_option_bool_flag_test() {
664 let command = Command::new("MyApp").option(
665 CommandOption::new("enable").arg(
666 Argument::with_name("enable")
667 .values_count(0..=1)
668 .validator(validate_type::<bool>()),
669 ),
670 );
671
672 let res1 = parse_with("--enable true", command.clone()).unwrap();
673 assert_eq!(
674 res1.options()
675 .get("enable")
676 .unwrap()
677 .get_arg()
678 .unwrap()
679 .get_values()[0],
680 "true".to_owned()
681 );
682
683 let res2 = parse_with("--enable false", command.clone()).unwrap();
684 assert_eq!(
685 res2.options()
686 .get("enable")
687 .unwrap()
688 .get_arg()
689 .unwrap()
690 .get_values()[0],
691 "false".to_owned()
692 );
693
694 let res3 = parse_with("--enable", command.clone()).unwrap();
695 assert!(res3.options().contains("enable"));
696
697 let res4 = parse_with("", command.clone()).unwrap();
698 assert!(!res4.options().contains("enable"));
699 }
700
701 #[test]
702 fn parse_result_arg_default_values_test1() {
703 let command = Command::new("MyApp")
704 .arg(Argument::with_name("min").default(1))
705 .arg(Argument::with_name("max"));
706
707 let result1 = parse_with("10", command.clone()).unwrap();
708 assert!(result1.args.get("min").unwrap().contains("1"));
709 assert!(result1.args.get("max").unwrap().contains("10"));
710
711 let result2 = parse_with("5 12", command.clone()).unwrap();
712 assert!(result2.args.get("min").unwrap().contains("5"));
713 assert!(result2.args.get("max").unwrap().contains("12"));
714 }
715
716 #[test]
717 #[should_panic]
718 fn parse_result_arg_default_values_test2() {
719 let _command = Command::new("MyApp")
720 .arg(Argument::with_name("min").default(1))
721 .arg(Argument::with_name("max").default(10));
722 }
723
724 #[test]
725 fn parse_result_option_default_values_test1() {
726 let command = Command::new("MyApp").option(
727 CommandOption::new("range")
728 .arg(Argument::with_name("start").default(1))
729 .arg(Argument::with_name("end")),
730 );
731
732 let result1 = parse_with("--range 22", command.clone()).unwrap();
733 assert!(result1
734 .options()
735 .get_args("range")
736 .unwrap()
737 .get("start")
738 .unwrap()
739 .contains("1"));
740 assert!(result1
741 .options()
742 .get_args("range")
743 .unwrap()
744 .get("end")
745 .unwrap()
746 .contains("22"));
747
748 let result2 = parse_with("--range 10 25", command.clone()).unwrap();
749 assert!(result2
750 .options()
751 .get_args("range")
752 .unwrap()
753 .get("start")
754 .unwrap()
755 .contains("10"));
756 assert!(result2
757 .options()
758 .get_args("range")
759 .unwrap()
760 .get("end")
761 .unwrap()
762 .contains("25"));
763 }
764
765 #[test]
766 #[should_panic]
767 fn parse_result_option_default_values_test2() {
768 let _command = Command::new("MyApp").option(
769 CommandOption::new("range")
770 .arg(Argument::with_name("start").default(1))
771 .arg(Argument::with_name("end").default(20)),
772 );
773 }
774
775 #[test]
776 fn parse_result_allow_multiple_test() {
777 let command = Command::new("MyApp").option(
778 CommandOption::new("values")
779 .multiple(true)
780 .arg(Argument::one_or_more("values")),
781 );
782
783 let result1 = parse_with("--values 5 6", command.clone()).unwrap();
784 assert!(result1.options().get_arg("values").unwrap().contains("5"));
785 assert!(result1.options().get_arg("values").unwrap().contains("6"));
786
787 let result2 = parse_with("--values 1 2 --values 3 4", command.clone()).unwrap();
788 assert!(result2.options().get_arg("values").unwrap().contains("1"));
789 assert!(result2.options().get_arg("values").unwrap().contains("2"));
790 assert!(result2.options().get_arg("values").unwrap().contains("3"));
791 assert!(result2.options().get_arg("values").unwrap().contains("4"));
792 }
793
794 #[test]
795 fn parse_global_option_test() {
796 let command = Command::new("MyApp")
797 .option(
798 CommandOption::new("color")
799 .global(true)
800 .arg(Argument::new().valid_values(vec!["red", "green", "blue"])),
801 )
802 .subcommand(Command::new("echo").arg(Argument::one_or_more("values")));
803
804 let result = parse_with("echo --color red -- hello world", command.clone()).unwrap();
805 assert_eq!(result.command_name(), "echo");
806 assert!(result.options().get_arg("color").unwrap().contains("red"));
807 assert!(result.args().get("values").unwrap().contains("hello"));
808 assert!(result.args().get("values").unwrap().contains("world"));
809 }
810
811 #[test]
812 fn parse_required_global_option_test() {
813 let command = Command::new("MyApp")
814 .option(CommandOption::new("flag").required(true).global(true))
815 .subcommand(Command::new("echo").arg(Argument::one_or_more("values")));
816
817 let result = parse_with("echo hello world", command.clone());
818 assert!(result.is_err());
819 assert_eq!(
820 result.unwrap_err().kind(),
821 &ErrorKind::MissingOption("flag".to_owned())
822 );
823
824 assert!(parse_with("echo --flag hello world", command.clone()).is_ok())
825 }
826
827 #[test]
828 fn value_of_test() {
829 let command = Command::new("MyApp").arg(Argument::with_name("color"));
830
831 let result = parse_with("red", command.clone()).unwrap();
832 assert_eq!("red", result.value_of("color").unwrap());
833 }
834
835 #[test]
836 fn values_of_test() {
837 let command = Command::new("MyApp").arg(Argument::one_or_more("colors"));
838
839 let result = parse_with("red blue green", command.clone()).unwrap();
840 assert_eq!(
841 vec!["red".to_owned(), "blue".to_owned(), "green".to_owned()],
842 result
843 .values_of("colors")
844 .unwrap()
845 .iter()
846 .cloned()
847 .collect::<Vec<String>>()
848 );
849 }
850
851 #[test]
852 fn value_of_option_test() {
853 let command = Command::new("MyApp")
854 .option(CommandOption::new("size").arg(Argument::with_name("size")));
855
856 let result = parse_with("--size sm", command.clone()).unwrap();
857 assert_eq!("sm", result.value_of_option("size").unwrap());
858 }
859
860 #[test]
861 fn values_of_option_test() {
862 let command = Command::new("MyApp")
863 .option(CommandOption::new("sizes").arg(Argument::one_or_more("sizes")));
864
865 let result = parse_with("--sizes sm md lg", command.clone()).unwrap();
866 assert_eq!(
867 vec!["sm".to_owned(), "md".to_owned(), "lg".to_owned()],
868 result
869 .values_of_option("sizes")
870 .unwrap()
871 .iter()
872 .cloned()
873 .collect::<Vec<String>>()
874 );
875 }
876
877 #[test]
878 fn value_of_as_test() {
879 let command = Command::new("MyApp").arg(Argument::with_name("numbers"));
880 let result = parse_with("65", command.clone()).unwrap();
881
882 assert_eq!(65, result.value_of_as::<i32>("numbers").unwrap());
883 }
884
885 #[test]
886 fn values_of_as_test() {
887 let command = Command::new("MyApp").arg(Argument::one_or_more("numbers"));
888 let result = parse_with("2 4 6", command.clone()).unwrap();
889
890 assert_eq!(
891 vec![2_i32, 4_i32, 6_i32],
892 result
893 .values_of_as::<i32>("numbers")
894 .unwrap()
895 .iter()
896 .cloned()
897 .collect::<Vec<i32>>()
898 );
899 }
900
901 #[test]
902 fn value_of_option_as_test() {
903 let command = Command::new("MyApp")
904 .option(CommandOption::new("size").arg(Argument::with_name("size")));
905 let result = parse_with("--size 202", command.clone()).unwrap();
906
907 assert_eq!(202_i64, result.value_of_option_as::<i64>("size").unwrap());
908 }
909
910 #[test]
911 fn values_of_option_as_test() {
912 let command = Command::new("MyApp")
913 .option(CommandOption::new("sizes").arg(Argument::one_or_more("sizes")));
914 let result = parse_with("--sizes 202 304", command.clone()).unwrap();
915
916 assert_eq!(
917 vec![202_i64, 304_i64],
918 result
919 .values_of_option_as::<i64>("sizes")
920 .unwrap()
921 .iter()
922 .cloned()
923 .collect::<Vec<i64>>()
924 );
925 }
926}