@@ -396,11 +396,25 @@ impl<'de> Deserializer<'de> for Value<'de> {
396396 visitor. visit_newtype_struct ( self )
397397 }
398398
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 >
400414 where
401415 V : Visitor < ' de > ,
402416 {
403- Err ( de :: value :: Error :: custom ( "unsupported type: tuple" ) )
417+ visitor . visit_seq ( ValueSeq :: new ( self . value ) )
404418 }
405419
406420 fn deserialize_struct < V > (
@@ -428,7 +442,6 @@ impl<'de> Deserializer<'de> for Value<'de> {
428442 }
429443
430444 unsupported_type ! ( deserialize_any, "any" ) ;
431- unsupported_type ! ( deserialize_seq, "seq" ) ;
432445 unsupported_type ! ( deserialize_map, "map" ) ;
433446 unsupported_type ! ( deserialize_identifier, "identifier" ) ;
434447}
@@ -498,6 +511,45 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
498511 }
499512}
500513
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+
501553#[ cfg( test) ]
502554mod tests {
503555 use serde:: Deserialize ;
@@ -537,6 +589,16 @@ mod tests {
537589 val : TestEnum ,
538590 }
539591
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+
540602 #[ test]
541603 fn test_request_extract ( ) {
542604 let mut router = Router :: < ( ) > :: build ( ) ;
@@ -632,6 +694,39 @@ mod tests {
632694 assert ! ( format!( "{:?}" , i) . contains( "unknown variant" ) ) ;
633695 }
634696
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+
635730 #[ test]
636731 fn test_extract_errors ( ) {
637732 let mut router = Router :: < ( ) > :: build ( ) ;
0 commit comments