1#![no_std]
3#![deny(missing_docs)]
4
5pub use noshell_macros as macros;
6pub use noshell_parser as parser;
7
8pub use macros::Parser;
9
10#[derive(Debug, PartialEq, Eq, thiserror::Error)]
12#[cfg_attr(feature = "defmt", derive(defmt::Format))]
13#[non_exhaustive]
14pub enum Error {
15 #[error(transparent)]
17 Parser(#[from] parser::Error),
18}
19
20#[cfg(test)]
21mod tests {
22 use googletest::prelude::{assert_that, eq, matches_pattern};
23
24 use crate as noshell;
25
26 #[test]
27 fn it_should_parse_args_with_simple_type() {
28 #[derive(Debug, noshell::Parser)]
29 struct MyArgs {
30 value: u32,
31 }
32
33 let argv = &["--value", "233"];
34 let res = MyArgs::parse(argv);
35
36 assert_that!(res, matches_pattern!(Ok(_)));
37
38 let args = res.unwrap();
39 assert_that!(args.value, eq(233));
40 }
41
42 #[test]
43 fn it_should_parse_args_with_option_type() {
44 #[derive(Debug, noshell::Parser)]
45 struct MyArgs {
46 value: Option<u32>,
47 }
48
49 let argv = &[];
50 let res = MyArgs::parse(argv);
51
52 assert_that!(res.is_ok(), eq(true));
53
54 let args = res.unwrap();
55 assert_that!(args.value, eq(None));
56
57 let argv = &["--value", "233"];
58 let res = MyArgs::parse(argv);
59
60 assert_that!(res.is_ok(), eq(true));
61
62 let args = res.unwrap();
63 assert_that!(args.value, eq(Some(233)));
64 }
65
66 #[test]
67 fn it_should_parse_args_with_option_option_type() {
68 #[derive(Debug, noshell::Parser)]
69 struct MyArgs {
70 value: Option<Option<u32>>,
71 }
72
73 let argv = &[];
74 let res = MyArgs::parse(argv);
75
76 assert_that!(res.is_ok(), eq(true));
77
78 let args = res.unwrap();
79 assert_that!(args.value, eq(None));
80
81 let argv = &["--value"];
82 let res = MyArgs::parse(argv);
83
84 assert_that!(res.is_ok(), eq(true));
85
86 let args = res.unwrap();
87 assert_that!(args.value, eq(Some(None)));
88 }
89
90 #[test]
91 fn it_should_parse_args_with_option_vec_type() {
92 use heapless::Vec;
93
94 #[derive(Debug, noshell::Parser)]
95 struct MyArgs {
96 value: Option<Vec<u32, 8>>,
97 }
98
99 let argv = &[];
101 let res = MyArgs::parse(argv);
102
103 assert_that!(res.is_ok(), eq(true));
104
105 let args = res.unwrap();
106 assert_that!(args.value.is_none(), eq(true));
107
108 let argv = &["--value"];
110 let res = MyArgs::parse(argv);
111
112 assert_that!(res.is_ok(), eq(false));
113
114 let argv = &["--value", "23"];
116 let res = MyArgs::parse(argv);
117
118 assert_that!(res.is_ok(), eq(true));
119 let args = res.unwrap();
120
121 assert_that!(args.value.is_some(), eq(true));
122 let vals = args.value.unwrap();
123
124 assert_that!(vals.is_empty(), eq(false));
125 assert_that!(vals.first().unwrap(), eq(&23));
126
127 let argv = &["--value", "23", "42", "72"];
129 let res = MyArgs::parse(argv);
130
131 assert_that!(res.is_ok(), eq(true));
132 let args = res.unwrap();
133
134 assert_that!(args.value.is_some(), eq(true));
135 let vals = args.value.unwrap();
136
137 assert_that!(vals.is_empty(), eq(false));
138 let mut iter = vals.iter();
139
140 assert_that!(iter.next().unwrap(), eq(&23));
141 assert_that!(iter.next().unwrap(), eq(&42));
142 assert_that!(iter.next().unwrap(), eq(&72));
143 assert_that!(iter.next(), eq(None));
144 }
145
146 #[test]
147 #[should_panic]
148 fn it_should_panic_at_parsing_args_with_option_vec_type() {
149 use heapless::Vec;
150
151 #[derive(Debug, noshell::Parser)]
152 struct MyArgs {
153 #[allow(unused)]
154 value: Option<Vec<u32, 4>>,
155 }
156
157 let argv = &["--value", "1", "2", "3", "4", "5"];
159 let _ = MyArgs::parse(argv);
160 }
161
162 #[test]
163 fn it_should_parse_args_with_vec_type() {
164 use heapless::Vec;
165
166 #[derive(Debug, noshell::Parser)]
167 struct MyArgs {
168 value: Vec<u32, 8>,
169 }
170
171 let argv = &[];
173 let res = MyArgs::parse(argv);
174
175 assert_that!(res.is_ok(), eq(false));
176
177 let argv = &["--value"];
179 let res = MyArgs::parse(argv);
180
181 assert_that!(res.is_ok(), eq(false));
182
183 let argv = &["--value", "23"];
185 let res = MyArgs::parse(argv);
186
187 assert_that!(res.is_ok(), eq(true));
188 let args = res.unwrap();
189
190 assert_that!(args.value.is_empty(), eq(false));
191 assert_that!(args.value.first().unwrap(), eq(&23));
192
193 let argv = &["--value", "23", "42", "72"];
195 let res = MyArgs::parse(argv);
196
197 assert_that!(res.is_ok(), eq(true));
198 let args = res.unwrap();
199
200 assert_that!(args.value.is_empty(), eq(false));
201 let mut iter = args.value.iter();
202
203 assert_that!(iter.next().unwrap(), eq(&23));
204 assert_that!(iter.next().unwrap(), eq(&42));
205 assert_that!(iter.next().unwrap(), eq(&72));
206 assert_that!(iter.next(), eq(None));
207 }
208
209 #[test]
210 #[should_panic]
211 fn it_should_panic_at_parsing_args_with_vec_type() {
212 use heapless::Vec;
213
214 #[derive(Debug, noshell::Parser)]
215 struct MyArgs {
216 #[allow(unused)]
217 value: Vec<u32, 4>,
218 }
219
220 let argv = &["--value", "1", "2", "3", "4", "5"];
222 let _ = MyArgs::parse(argv);
223 }
224}