@@ -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 ;
@@ -537,6 +589,16 @@ mod tests {
537
589
val : TestEnum ,
538
590
}
539
591
592
+ #[ derive( Debug , Deserialize ) ]
593
+ struct TestSeq1 {
594
+ tail : Vec < String > ,
595
+ }
596
+
597
+ #[ derive( Debug , Deserialize ) ]
598
+ struct TestSeq2 {
599
+ tail : ( String , String , String ) ,
600
+ }
601
+
540
602
#[ test]
541
603
fn test_request_extract ( ) {
542
604
let mut router = Router :: < ( ) > :: build ( ) ;
@@ -632,6 +694,39 @@ mod tests {
632
694
assert ! ( format!( "{:?}" , i) . contains( "unknown variant" ) ) ;
633
695
}
634
696
697
+ #[ test]
698
+ fn test_extract_seq ( ) {
699
+ let mut router = Router :: < ( ) > :: build ( ) ;
700
+ router. path ( "/path/to/{tail:.*}" , ( ) ) ;
701
+ let router = router. finish ( ) ;
702
+
703
+ let mut path = Path :: new ( "/path/to/tail/with/slash%2fes" ) ;
704
+ assert ! ( router. recognize( & mut path) . is_some( ) ) ;
705
+
706
+ let i: ( String , ) = de:: Deserialize :: deserialize ( PathDeserializer :: new ( & path) ) . unwrap ( ) ;
707
+ assert_eq ! ( i. 0 , String :: from( "tail/with/slash/es" ) ) ;
708
+
709
+ let i: TestSeq1 = de:: Deserialize :: deserialize ( PathDeserializer :: new ( & path) ) . unwrap ( ) ;
710
+ assert_eq ! (
711
+ i. tail,
712
+ vec![
713
+ String :: from( "tail" ) ,
714
+ String :: from( "with" ) ,
715
+ String :: from( "slash/es" )
716
+ ]
717
+ ) ;
718
+
719
+ let i: TestSeq2 = de:: Deserialize :: deserialize ( PathDeserializer :: new ( & path) ) . unwrap ( ) ;
720
+ assert_eq ! (
721
+ i. tail,
722
+ (
723
+ String :: from( "tail" ) ,
724
+ String :: from( "with" ) ,
725
+ String :: from( "slash/es" )
726
+ )
727
+ ) ;
728
+ }
729
+
635
730
#[ test]
636
731
fn test_extract_errors ( ) {
637
732
let mut router = Router :: < ( ) > :: build ( ) ;
0 commit comments