11use std:: iter:: IntoIterator ;
2+ use std:: collections:: HashSet ;
23
34use usageparser:: { UsageParser , UsageToken } ;
45
@@ -79,7 +80,7 @@ pub struct Arg<'n, 'l, 'h, 'g, 'p, 'r> {
7980 #[ doc( hidden) ]
8081 pub group : Option < & ' g str > ,
8182 #[ doc( hidden) ]
82- pub val_names : Option < Vec < & ' p str > > ,
83+ pub val_names : Option < Vec < & ' n str > > ,
8384 #[ doc( hidden) ]
8485 pub num_vals : Option < u8 > ,
8586 #[ doc( hidden) ]
@@ -229,34 +230,57 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
229230 let mut required = false ;
230231 let mut takes_value = false ;
231232 let mut multiple = false ;
233+ let mut num_names = 1 ;
234+ let mut name_first = false ;
235+ let mut consec_names = false ;
236+ let mut val_names = HashSet :: new ( ) ;
232237
233238 let parser = UsageParser :: with_usage ( u) ;
234239 for_match ! { parser,
235240 UsageToken :: Name ( n, req) => {
236- if name. is_none( ) {
241+ if consec_names {
242+ num_names += 1 ;
243+ }
244+ let mut use_req = false ;
245+ let mut use_name = false ;
246+ if name. is_none( ) && long. is_none( ) && short. is_none( ) {
247+ name_first = true ;
248+ use_name = true ;
249+ use_req = true ;
250+ } else if let Some ( l) = long {
251+ if l == name. unwrap_or( "" ) {
252+ if !name_first {
253+ use_name = true ;
254+ use_req = true ;
255+ }
256+ }
257+ } else {
258+ // starting with short
259+ if !name_first {
260+ use_name = true ;
261+ use_req = true ;
262+ }
263+ }
264+ if use_name && !consec_names {
237265 name = Some ( n) ;
266+ }
267+ if use_req && !consec_names {
238268 if let Some ( r) = req {
239269 required = r;
240270 }
241- } else if let Some ( l) = long {
242- if l == name. unwrap( ) {
243- if let Some ( r) = req {
244- required = r;
245- }
246- name = Some ( n) ;
247- } else if n != l {
248- name = Some ( n) ;
249- }
250-
251271 }
252272 if short. is_some( ) || long. is_some( ) {
273+ val_names. insert( n) ;
253274 takes_value = true ;
254275 }
276+ consec_names = true ;
255277 } ,
256278 UsageToken :: Short ( s) => {
279+ consec_names = false ;
257280 short = Some ( s) ;
258281 } ,
259282 UsageToken :: Long ( l) => {
283+ consec_names = false ;
260284 long = Some ( l) ;
261285 if name. is_none( ) {
262286 name = Some ( l) ;
@@ -270,6 +294,15 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
270294 }
271295 }
272296
297+ if let Some ( l) = long {
298+ val_names. remove ( l) ;
299+ if val_names. len ( ) > 1 {
300+ if name. unwrap ( ) != l && !name_first {
301+ name = Some ( l) ;
302+ }
303+ }
304+ }
305+
273306 Arg {
274307 name : name. unwrap ( ) ,
275308 short : short,
@@ -282,8 +315,8 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
282315 possible_vals : None ,
283316 blacklist : None ,
284317 requires : None ,
285- num_vals : None ,
286- val_names : None ,
318+ num_vals : if num_names > 1 { Some ( num_names ) } else { None } ,
319+ val_names : if val_names . len ( ) > 1 { Some ( val_names . iter ( ) . map ( |s| * s ) . collect :: < Vec < _ > > ( ) ) } else { None } ,
287320 max_vals : None ,
288321 min_vals : None ,
289322 group : None ,
@@ -765,8 +798,8 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
765798 /// # ).get_matches();
766799 pub fn value_names < T , I > ( mut self , names : I )
767800 -> Arg < ' n , ' l , ' h , ' g , ' p , ' r >
768- where T : AsRef < str > + ' p ,
769- I : IntoIterator < Item =& ' p T > {
801+ where T : AsRef < str > + ' n ,
802+ I : IntoIterator < Item =& ' n T > {
770803 if let Some ( ref mut vec) = self . val_names {
771804 names. into_iter ( ) . map ( |s| vec. push ( s. as_ref ( ) ) ) . collect :: < Vec < _ > > ( ) ;
772805 } else {
0 commit comments