@@ -396,11 +396,25 @@ impl<'de> Deserializer<'de> for Value<'de> {
396
396
visitor. visit_newtype_struct ( self )
397
397
}
398
398
399
- fn deserialize_tuple < V > ( self , _: usize , _: V ) -> Result < V :: Value , Self :: Error >
399
+ fn deserialize_tuple < V > ( self , len : usize , visitor : V ) -> Result < V :: Value , Self :: Error >
400
+ where
401
+ V : Visitor < ' de > ,
402
+ {
403
+ let value_seq = ValueSeq :: new ( self . value ) ;
404
+ if len == value_seq. len ( ) {
405
+ visitor. visit_seq ( value_seq)
406
+ } else {
407
+ Err ( de:: value:: Error :: custom (
408
+ "path and tuple lengths don't match" ,
409
+ ) )
410
+ }
411
+ }
412
+
413
+ fn deserialize_seq < V > ( self , visitor : V ) -> Result < V :: Value , Self :: Error >
400
414
where
401
415
V : Visitor < ' de > ,
402
416
{
403
- Err ( de :: value :: Error :: custom ( "unsupported type: tuple" ) )
417
+ visitor . visit_seq ( ValueSeq :: new ( self . value ) )
404
418
}
405
419
406
420
fn deserialize_struct < V > (
@@ -428,7 +442,6 @@ impl<'de> Deserializer<'de> for Value<'de> {
428
442
}
429
443
430
444
unsupported_type ! ( deserialize_any, "any" ) ;
431
- unsupported_type ! ( deserialize_seq, "seq" ) ;
432
445
unsupported_type ! ( deserialize_map, "map" ) ;
433
446
unsupported_type ! ( deserialize_identifier, "identifier" ) ;
434
447
}
@@ -498,6 +511,45 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
498
511
}
499
512
}
500
513
514
+ struct ValueSeq < ' de > {
515
+ value : & ' de str ,
516
+ elems : std:: str:: Split < ' de , char > ,
517
+ }
518
+
519
+ impl < ' de > ValueSeq < ' de > {
520
+ fn new ( value : & ' de str ) -> Self {
521
+ Self {
522
+ value,
523
+ elems : value. split ( '/' ) ,
524
+ }
525
+ }
526
+
527
+ fn len ( & self ) -> usize {
528
+ self . value . split ( '/' ) . filter ( |s| !s. is_empty ( ) ) . count ( )
529
+ }
530
+ }
531
+
532
+ impl < ' de > de:: SeqAccess < ' de > for ValueSeq < ' de > {
533
+ type Error = de:: value:: Error ;
534
+
535
+ fn next_element_seed < T > ( & mut self , seed : T ) -> Result < Option < T :: Value > , Self :: Error >
536
+ where
537
+ T : de:: DeserializeSeed < ' de > ,
538
+ {
539
+ for elem in & mut self . elems {
540
+ if !elem. is_empty ( ) {
541
+ return seed. deserialize ( Value { value : elem } ) . map ( Some ) ;
542
+ }
543
+ }
544
+
545
+ Ok ( None )
546
+ }
547
+
548
+ fn size_hint ( & self ) -> Option < usize > {
549
+ Some ( self . len ( ) )
550
+ }
551
+ }
552
+
501
553
#[ cfg( test) ]
502
554
mod tests {
503
555
use serde:: Deserialize ;
@@ -532,6 +584,16 @@ mod tests {
532
584
val : TestEnum ,
533
585
}
534
586
587
+ #[ derive( Debug , Deserialize ) ]
588
+ struct TestSeq1 {
589
+ tail : Vec < String > ,
590
+ }
591
+
592
+ #[ derive( Debug , Deserialize ) ]
593
+ struct TestSeq2 {
594
+ tail : ( String , String , String ) ,
595
+ }
596
+
535
597
#[ test]
536
598
fn test_request_extract ( ) {
537
599
let mut router = Router :: < ( ) > :: build ( ) ;
@@ -627,6 +689,39 @@ mod tests {
627
689
assert ! ( format!( "{:?}" , i) . contains( "unknown variant" ) ) ;
628
690
}
629
691
692
+ #[ test]
693
+ fn test_extract_seq ( ) {
694
+ let mut router = Router :: < ( ) > :: build ( ) ;
695
+ router. path ( "/path/to/{tail:.*}" , ( ) ) ;
696
+ let router = router. finish ( ) ;
697
+
698
+ let mut path = Path :: new ( "/path/to/tail/with/slash%2fes" ) ;
699
+ assert ! ( router. recognize( & mut path) . is_some( ) ) ;
700
+
701
+ let i: ( String , ) = de:: Deserialize :: deserialize ( PathDeserializer :: new ( & path) ) . unwrap ( ) ;
702
+ assert_eq ! ( i. 0 , String :: from( "tail/with/slash/es" ) ) ;
703
+
704
+ let i: TestSeq1 = de:: Deserialize :: deserialize ( PathDeserializer :: new ( & path) ) . unwrap ( ) ;
705
+ assert_eq ! (
706
+ i. tail,
707
+ vec![
708
+ String :: from( "tail" ) ,
709
+ String :: from( "with" ) ,
710
+ String :: from( "slash/es" )
711
+ ]
712
+ ) ;
713
+
714
+ let i: TestSeq2 = de:: Deserialize :: deserialize ( PathDeserializer :: new ( & path) ) . unwrap ( ) ;
715
+ assert_eq ! (
716
+ i. tail,
717
+ (
718
+ String :: from( "tail" ) ,
719
+ String :: from( "with" ) ,
720
+ String :: from( "slash/es" )
721
+ )
722
+ ) ;
723
+ }
724
+
630
725
#[ test]
631
726
fn test_extract_errors ( ) {
632
727
let mut router = Router :: < ( ) > :: build ( ) ;
0 commit comments