• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
2 // Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
3 // Ana Hobden (@hoverbear) <operator@hoverbear.org>
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 //
11 // This work was derived from Structopt (https://github.com/TeXitoi/structopt)
12 // commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
13 // MIT/Apache 2.0 license.
14 
15 use clap::error::ErrorKind;
16 use clap::Parser;
17 use std::num::ParseIntError;
18 
19 pub const DISPLAY_ORDER: usize = 2;
20 
21 // Check if the global settings compile
22 #[derive(Parser, Debug, PartialEq, Eq)]
23 #[command(group = clap::ArgGroup::new("foo"))]
24 struct Opt {
25     #[arg(
26         long = "x",
27         display_order = DISPLAY_ORDER,
28         next_line_help = true,
29         default_value = "0",
30         require_equals = true,
31     )]
32     x: i32,
33 
34     #[arg(short = 'l', long = "level", aliases = ["set-level", "lvl"])]
35     level: String,
36 
37     #[arg(long("values"))]
38     values: Vec<i32>,
39 
40     #[arg(id = "FILE", requires_if("FILE", "values"))]
41     files: Vec<String>,
42 }
43 
44 #[test]
test_slice()45 fn test_slice() {
46     assert_eq!(
47         Opt {
48             x: 0,
49             level: "1".to_string(),
50             files: Vec::new(),
51             values: vec![],
52         },
53         Opt::try_parse_from(["test", "-l", "1"]).unwrap()
54     );
55     assert_eq!(
56         Opt {
57             x: 0,
58             level: "1".to_string(),
59             files: Vec::new(),
60             values: vec![],
61         },
62         Opt::try_parse_from(["test", "--level", "1"]).unwrap()
63     );
64     assert_eq!(
65         Opt {
66             x: 0,
67             level: "1".to_string(),
68             files: Vec::new(),
69             values: vec![],
70         },
71         Opt::try_parse_from(["test", "--set-level", "1"]).unwrap()
72     );
73     assert_eq!(
74         Opt {
75             x: 0,
76             level: "1".to_string(),
77             files: Vec::new(),
78             values: vec![],
79         },
80         Opt::try_parse_from(["test", "--lvl", "1"]).unwrap()
81     );
82 }
83 
84 #[test]
test_multi_args()85 fn test_multi_args() {
86     assert_eq!(
87         Opt {
88             x: 0,
89             level: "1".to_string(),
90             files: vec!["file".to_string()],
91             values: vec![],
92         },
93         Opt::try_parse_from(["test", "-l", "1", "file"]).unwrap()
94     );
95     assert_eq!(
96         Opt {
97             x: 0,
98             level: "1".to_string(),
99             files: vec!["FILE".to_string()],
100             values: vec![1],
101         },
102         Opt::try_parse_from(["test", "-l", "1", "--values", "1", "--", "FILE"]).unwrap()
103     );
104 }
105 
106 #[test]
test_multi_args_fail()107 fn test_multi_args_fail() {
108     let result = Opt::try_parse_from(["test", "-l", "1", "--", "FILE"]);
109     assert!(result.is_err());
110 }
111 
112 #[test]
test_bool()113 fn test_bool() {
114     assert_eq!(
115         Opt {
116             x: 1,
117             level: "1".to_string(),
118             files: vec![],
119             values: vec![],
120         },
121         Opt::try_parse_from(["test", "-l", "1", "--x=1"]).unwrap()
122     );
123     let result = Opt::try_parse_from(["test", "-l", "1", "--x", "1"]);
124     assert!(result.is_err());
125     assert_eq!(result.unwrap_err().kind(), ErrorKind::NoEquals);
126 }
127 
parse_hex(input: &str) -> Result<u64, ParseIntError>128 fn parse_hex(input: &str) -> Result<u64, ParseIntError> {
129     u64::from_str_radix(input, 16)
130 }
131 
132 #[derive(Parser, PartialEq, Debug)]
133 struct HexOpt {
134     #[arg(short, value_parser = parse_hex)]
135     number: u64,
136 }
137 
138 #[test]
139 #[cfg(feature = "error-context")]
test_parse_hex_function_path()140 fn test_parse_hex_function_path() {
141     assert_eq!(
142         HexOpt { number: 5 },
143         HexOpt::try_parse_from(["test", "-n", "5"]).unwrap()
144     );
145     assert_eq!(
146         HexOpt {
147             number: 0x00ab_cdef
148         },
149         HexOpt::try_parse_from(["test", "-n", "abcdef"]).unwrap()
150     );
151 
152     let err = HexOpt::try_parse_from(["test", "-n", "gg"]).unwrap_err();
153     assert!(
154         err.to_string().contains("invalid digit found in string"),
155         "{}",
156         err
157     );
158 }
159