@@ -300,6 +300,117 @@ impl<'a> Iterator for Varargs<'a> {
300
300
}
301
301
}
302
302
303
+ // Return a second token.
304
+ macro_rules! replace_expr {
305
+ ( $_t: tt $sub: expr) => {
306
+ $sub
307
+ } ;
308
+ }
309
+
310
+ // Count parameters.
311
+ macro_rules! count_tts {
312
+ ( $( $tts: tt) * ) => {
313
+ 0usize $( + replace_expr!( $tts 1usize ) ) *
314
+ } ;
315
+ }
316
+
317
+ // Convert from Varargs to tuples, implement traits.
318
+ macro_rules! varargs_into_tuple {
319
+ ( $( $params: ident) ,* ) => {
320
+ impl <' a, $( $params: FromVariant ) ,* > std:: convert:: TryFrom <Varargs <' a>> for ( $( $params, ) * ) {
321
+ type Error = VarargsError ;
322
+
323
+ #[ inline]
324
+ fn try_from( value: Varargs <' a>) -> Result <Self , Self :: Error > {
325
+ const EXPECTED : usize = count_tts!( $( $params) * ) ;
326
+ let args = & value. args;
327
+ if args. len( ) == EXPECTED {
328
+ #[ allow( unused_variables, unused_mut) ]
329
+ let mut i: usize = 0 ;
330
+ #[ allow( clippy:: eval_order_dependence) ]
331
+ Ok ( (
332
+ $( {
333
+ i += 1 ;
334
+ $params:: from_variant( args[ i - 1 ] ) ?
335
+ } , ) *
336
+ ) )
337
+ } else {
338
+ Err ( ArgumentLengthError {
339
+ passed: args. len( ) ,
340
+ expected: EXPECTED ,
341
+ } . into( ) )
342
+ }
343
+ }
344
+ }
345
+ } ;
346
+ }
347
+
348
+ // Define up to the length supported by standard library.
349
+ varargs_into_tuple ! ( ) ;
350
+ varargs_into_tuple ! ( A ) ;
351
+ varargs_into_tuple ! ( A , B ) ;
352
+ varargs_into_tuple ! ( A , B , C ) ;
353
+ varargs_into_tuple ! ( A , B , C , D ) ;
354
+ varargs_into_tuple ! ( A , B , C , D , E ) ;
355
+ varargs_into_tuple ! ( A , B , C , D , E , F ) ;
356
+ varargs_into_tuple ! ( A , B , C , D , E , F , G ) ;
357
+ varargs_into_tuple ! ( A , B , C , D , E , F , G , H ) ;
358
+ varargs_into_tuple ! ( A , B , C , D , E , F , G , H , I ) ;
359
+ varargs_into_tuple ! ( A , B , C , D , E , F , G , H , I , J ) ;
360
+ varargs_into_tuple ! ( A , B , C , D , E , F , G , H , I , J , K ) ;
361
+ varargs_into_tuple ! ( A , B , C , D , E , F , G , H , I , J , K , L ) ;
362
+
363
+ /// All possible error types for convert from Varargs.
364
+ #[ derive( Debug ) ]
365
+ pub enum VarargsError {
366
+ ArgumentLengthError ( ArgumentLengthError ) ,
367
+ FromVariantError ( FromVariantError ) ,
368
+ }
369
+
370
+ impl std:: error:: Error for VarargsError { }
371
+ impl std:: fmt:: Display for VarargsError {
372
+ #[ inline]
373
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
374
+ match & self {
375
+ VarargsError :: ArgumentLengthError ( e) => e. fmt ( f) ,
376
+ VarargsError :: FromVariantError ( e) => e. fmt ( f) ,
377
+ }
378
+ }
379
+ }
380
+
381
+ impl From < ArgumentLengthError > for VarargsError {
382
+ #[ inline]
383
+ fn from ( value : ArgumentLengthError ) -> Self {
384
+ Self :: ArgumentLengthError ( value)
385
+ }
386
+ }
387
+
388
+ impl From < FromVariantError > for VarargsError {
389
+ #[ inline]
390
+ fn from ( value : FromVariantError ) -> Self {
391
+ Self :: FromVariantError ( value)
392
+ }
393
+ }
394
+
395
+ /// Error to argument lengths do not match.
396
+ #[ derive( Debug ) ]
397
+ pub struct ArgumentLengthError {
398
+ passed : usize ,
399
+ expected : usize ,
400
+ }
401
+
402
+ impl std:: error:: Error for ArgumentLengthError { }
403
+ impl std:: fmt:: Display for ArgumentLengthError {
404
+ #[ inline]
405
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
406
+ write ! (
407
+ f,
408
+ "Argument lengths do not match. passed {}, expected {}" ,
409
+ self . passed, self . expected
410
+ )
411
+ }
412
+ }
413
+
303
414
/// Trait for structures that can be parsed from `Varargs`.
304
415
///
305
416
/// This trait can be derived for structure types where each type implements `FromVariant`.
0 commit comments