@@ -21,21 +21,31 @@ impl Context {
21
21
let flags_val = match flags {
22
22
Some ( flags) => {
23
23
for flag in flags {
24
- if let Some ( index) = flag. option_index ( & parsed_args) {
25
- parsed_args. remove ( index) ;
24
+ let mut found_flag = false ;
25
+ loop {
26
+ if let Some ( index) = flag. option_index ( & parsed_args) {
27
+ found_flag = true ;
28
+ parsed_args. remove ( index) ;
26
29
27
- let val = if flag. flag_type != FlagType :: Bool {
28
- if parsed_args. len ( ) <= index {
29
- None
30
+ let val = if flag. flag_type != FlagType :: Bool {
31
+ if parsed_args. len ( ) <= index {
32
+ None
33
+ } else {
34
+ Some ( parsed_args. remove ( index) )
35
+ }
30
36
} else {
31
- Some ( parsed_args. remove ( index) )
37
+ None
38
+ } ;
39
+ v. push ( ( flag. name . to_string ( ) , flag. value ( val) ) ) ;
40
+ if !flag. multiple {
41
+ break ;
32
42
}
33
43
} else {
34
- None
35
- } ;
36
- v . push ( ( flag . name . to_string ( ) , flag . value ( val ) ) )
37
- } else {
38
- v . push ( ( flag . name . to_string ( ) , Err ( FlagError :: NotFound ) ) )
44
+ if !found_flag {
45
+ v . push ( ( flag . name . to_string ( ) , Err ( FlagError :: NotFound ) ) ) ;
46
+ }
47
+ break ;
48
+ }
39
49
}
40
50
}
41
51
Some ( v)
@@ -66,6 +76,15 @@ impl Context {
66
76
}
67
77
}
68
78
79
+ // Get flag values for repeated flags
80
+ fn result_flag_value_vec ( & self , name : & str ) -> Vec :: < Result < FlagValue , FlagError > > {
81
+ self . flags . as_ref ( ) . unwrap ( ) . iter ( ) . filter ( |flag| flag. 0 == name)
82
+ . map ( |f| match & f. 1 {
83
+ Ok ( val) => Ok ( val. to_owned ( ) ) ,
84
+ Err ( e) => Err ( e. to_owned ( ) ) ,
85
+ } ) . collect :: < Vec < _ > > ( )
86
+ }
87
+
69
88
/// Get bool flag
70
89
///
71
90
/// Example
@@ -111,6 +130,34 @@ impl Context {
111
130
}
112
131
}
113
132
133
+ /// Get string flags for repeated flags
134
+ ///
135
+ /// Example
136
+ ///
137
+ /// ```
138
+ /// use seahorse::Context;
139
+ ///
140
+ /// fn action(c: &Context) {
141
+ /// for s in c.string_flag_vec("string") {
142
+ /// match s {
143
+ /// Ok(s) => println!("{}", s),
144
+ /// Err(e) => println!("{}", e)
145
+ /// }
146
+ /// }
147
+ /// }
148
+ /// ```
149
+ pub fn string_flag_vec ( & self , name : & str ) -> Vec < Result < String , FlagError > > {
150
+ let r = self . result_flag_value_vec ( name) ;
151
+
152
+ r. iter ( ) . map ( |r|
153
+ {
154
+ match r {
155
+ Ok ( FlagValue :: String ( val) ) => Ok ( val. clone ( ) ) ,
156
+ _ => Err ( FlagError :: TypeError ) ,
157
+ }
158
+ } ) . collect :: < Vec < _ > > ( )
159
+ }
160
+
114
161
/// Get int flag
115
162
///
116
163
/// Example
@@ -133,6 +180,34 @@ impl Context {
133
180
}
134
181
}
135
182
183
+ /// Get int flags for repeated flags
184
+ ///
185
+ /// Example
186
+ ///
187
+ /// ```
188
+ /// use seahorse::Context;
189
+ ///
190
+ /// fn action(c: &Context) {
191
+ /// for i in c.int_flag_vec("int") {
192
+ /// match i {
193
+ /// Ok(i) => println!("{}", i),
194
+ /// Err(e) => println!("{}", e)
195
+ /// }
196
+ /// }
197
+ /// }
198
+ /// ```
199
+ pub fn int_flag_vec ( & self , name : & str ) -> Vec < Result < isize , FlagError > > {
200
+ let r = self . result_flag_value_vec ( name) ;
201
+
202
+ r. iter ( ) . map ( |r|
203
+ {
204
+ match r {
205
+ Ok ( FlagValue :: Int ( val) ) => Ok ( val. clone ( ) ) ,
206
+ _ => Err ( FlagError :: TypeError ) ,
207
+ }
208
+ } ) . collect :: < Vec < _ > > ( )
209
+ }
210
+
136
211
/// Get Uint flag
137
212
///
138
213
/// Example
@@ -155,6 +230,34 @@ impl Context {
155
230
}
156
231
}
157
232
233
+ /// Get uint flags for repeated flags
234
+ ///
235
+ /// Example
236
+ ///
237
+ /// ```
238
+ /// use seahorse::Context;
239
+ ///
240
+ /// fn action(c: &Context) {
241
+ /// for i in c.uint_flag_vec("uint") {
242
+ /// match i {
243
+ /// Ok(i) => println!("{}", i),
244
+ /// Err(e) => println!("{}", e)
245
+ /// }
246
+ /// }
247
+ /// }
248
+ /// ```
249
+ pub fn uint_flag_vec ( & self , name : & str ) -> Vec < Result < usize , FlagError > > {
250
+ let r = self . result_flag_value_vec ( name) ;
251
+
252
+ r. iter ( ) . map ( |r|
253
+ {
254
+ match r {
255
+ Ok ( FlagValue :: Uint ( val) ) => Ok ( val. clone ( ) ) ,
256
+ _ => Err ( FlagError :: TypeError ) ,
257
+ }
258
+ } ) . collect :: < Vec < _ > > ( )
259
+ }
260
+
158
261
/// Get float flag
159
262
///
160
263
/// Example
@@ -177,6 +280,36 @@ impl Context {
177
280
}
178
281
}
179
282
283
+ /// Get float flags for repeated flags
284
+ ///
285
+ /// Example
286
+ ///
287
+ /// ```
288
+ /// use seahorse::Context;
289
+ ///
290
+ /// fn action(c: &Context) {
291
+ /// for f in c.float_flag_vec("float") {
292
+ /// match f {
293
+ /// Ok(f) => println!("{}", f),
294
+ /// Err(e) => println!("{}", e)
295
+ /// }
296
+ /// }
297
+ /// }
298
+ /// ```
299
+ pub fn float_flag_vec ( & self , name : & str ) -> Vec < Result < f64 , FlagError > > {
300
+ let r = self . result_flag_value_vec ( name) ;
301
+
302
+ // I would like to map the Result<FlagValue, FlagError> to Result<f64, FlagError>
303
+
304
+ r. iter ( ) . map ( |r|
305
+ {
306
+ match * r {
307
+ Ok ( FlagValue :: Float ( val) ) => Ok ( val) ,
308
+ _ => Err ( FlagError :: TypeError ) ,
309
+ }
310
+ } ) . collect :: < Vec < _ > > ( )
311
+ }
312
+
180
313
/// Display help
181
314
///
182
315
/// Example
@@ -213,6 +346,8 @@ mod tests {
213
346
"1234567654321" . to_string( ) ,
214
347
"--float" . to_string( ) ,
215
348
"1.23" . to_string( ) ,
349
+ "--float" . to_string( ) ,
350
+ "1.44" . to_string( ) ,
216
351
"--invalid_float" . to_string( ) ,
217
352
"invalid" . to_string( ) ,
218
353
] ;
@@ -221,7 +356,7 @@ mod tests {
221
356
Flag :: new( "string" , FlagType :: String ) ,
222
357
Flag :: new( "int" , FlagType :: Int ) ,
223
358
Flag :: new( "uint" , FlagType :: Uint ) ,
224
- Flag :: new( "float" , FlagType :: Float ) ,
359
+ Flag :: new( "float" , FlagType :: Float ) . multiple ( ) ,
225
360
Flag :: new( "invalid_float" , FlagType :: Float ) ,
226
361
Flag :: new( "not_specified" , FlagType :: String ) ,
227
362
] ;
0 commit comments