@@ -27,6 +27,9 @@ macro_rules! unsupported_type {
2727
2828macro_rules! parse_single_value {
2929 ( $trait_fn: ident) => {
30+ parse_single_value!( $trait_fn, $trait_fn) ;
31+ } ;
32+ ( $trait_fn: ident, $visit_fn: ident) => {
3033 fn $trait_fn<V >( self , visitor: V ) -> Result <V :: Value , Self :: Error >
3134 where
3235 V : Visitor <' de>,
@@ -43,7 +46,7 @@ macro_rules! parse_single_value {
4346 Value {
4447 value: & self . path[ 0 ] ,
4548 }
46- . $trait_fn ( visitor)
49+ . $visit_fn ( visitor)
4750 }
4851 }
4952 } ;
@@ -205,11 +208,11 @@ impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T>
205208 } )
206209 }
207210
208- unsupported_type ! ( deserialize_any, "'any'" ) ;
209211 unsupported_type ! ( deserialize_option, "Option<T>" ) ;
210212 unsupported_type ! ( deserialize_identifier, "identifier" ) ;
211213 unsupported_type ! ( deserialize_ignored_any, "ignored_any" ) ;
212214
215+ parse_single_value ! ( deserialize_any) ;
213216 parse_single_value ! ( deserialize_bool) ;
214217 parse_single_value ! ( deserialize_i8) ;
215218 parse_single_value ! ( deserialize_i16) ;
@@ -427,7 +430,39 @@ impl<'de> Deserializer<'de> for Value<'de> {
427430 Err ( de:: value:: Error :: custom ( "unsupported type: tuple struct" ) )
428431 }
429432
430- unsupported_type ! ( deserialize_any, "any" ) ;
433+ fn deserialize_any < V > ( self , visitor : V ) -> Result < V :: Value , Self :: Error >
434+ where
435+ V : Visitor < ' de > ,
436+ {
437+ let decoded = FULL_QUOTER
438+ . with ( |q| q. requote_str_lossy ( self . value ) )
439+ . map ( Cow :: Owned )
440+ . unwrap_or ( Cow :: Borrowed ( self . value ) ) ;
441+
442+ let s = decoded. as_ref ( ) ;
443+ // We have to do it manually here on behalf of serde.
444+ if let Ok ( v) = s. parse :: < u64 > ( ) {
445+ if let Ok ( v) = u32:: try_from ( v) {
446+ return visitor. visit_u32 ( v) ;
447+ }
448+
449+ return visitor. visit_u64 ( v) ;
450+ }
451+
452+ if let Ok ( v) = s. parse :: < i64 > ( ) {
453+ if let Ok ( v) = i32:: try_from ( v) {
454+ return visitor. visit_i32 ( v) ;
455+ }
456+
457+ return visitor. visit_i64 ( v) ;
458+ }
459+
460+ match decoded {
461+ Cow :: Borrowed ( value) => visitor. visit_borrowed_str ( value) ,
462+ Cow :: Owned ( value) => visitor. visit_string ( value) ,
463+ }
464+ }
465+
431466 unsupported_type ! ( deserialize_seq, "seq" ) ;
432467 unsupported_type ! ( deserialize_map, "map" ) ;
433468 unsupported_type ! ( deserialize_identifier, "identifier" ) ;
@@ -704,6 +739,119 @@ mod tests {
704739 assert_eq ! ( vals. value, "/" ) ;
705740 }
706741
742+ #[ test]
743+ fn deserialize_path_decode_any ( ) {
744+ #[ derive( Debug , PartialEq ) ]
745+ pub enum AnyEnumCustom {
746+ String ( String ) ,
747+ Int ( u32 ) ,
748+ Other ,
749+ }
750+
751+ impl < ' de > Deserialize < ' de > for AnyEnumCustom {
752+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
753+ where
754+ D : serde:: Deserializer < ' de > ,
755+ {
756+ struct Vis ;
757+ impl < ' de > Visitor < ' de > for Vis {
758+ type Value = AnyEnumCustom ;
759+
760+ fn expecting < ' a > ( & self , f : & mut std:: fmt:: Formatter < ' a > ) -> std:: fmt:: Result {
761+ write ! ( f, "my thing" )
762+ }
763+
764+ fn visit_u32 < E > ( self , v : u32 ) -> Result < Self :: Value , E >
765+ where
766+ E : serde:: de:: Error ,
767+ {
768+ Ok ( AnyEnumCustom :: Int ( v) )
769+ }
770+
771+ fn visit_u64 < E > ( self , v : u64 ) -> Result < Self :: Value , E >
772+ where
773+ E : serde:: de:: Error ,
774+ {
775+ match u32:: try_from ( v) {
776+ Ok ( v) => Ok ( AnyEnumCustom :: Int ( v) ) ,
777+ Err ( _) => Ok ( AnyEnumCustom :: String ( format ! ( "some str: {v}" ) ) ) ,
778+ }
779+ }
780+
781+ fn visit_i64 < E > ( self , v : i64 ) -> Result < Self :: Value , E >
782+ where
783+ E : serde:: de:: Error ,
784+ {
785+ match u32:: try_from ( v) {
786+ Ok ( v) => Ok ( AnyEnumCustom :: Int ( v) ) ,
787+ Err ( _) => Ok ( AnyEnumCustom :: String ( format ! ( "some str: {v}" ) ) ) ,
788+ }
789+ }
790+
791+ fn visit_str < E : serde:: de:: Error > ( self , v : & str ) -> Result < Self :: Value , E > {
792+ v. parse ( ) . map ( AnyEnumCustom :: Int ) . or_else ( |_| {
793+ Ok ( match v {
794+ "other" => AnyEnumCustom :: Other ,
795+ _ => AnyEnumCustom :: String ( format ! ( "some str: {v}" ) ) ,
796+ } )
797+ } )
798+ }
799+ }
800+
801+ deserializer. deserialize_any ( Vis )
802+ }
803+ }
804+
805+ #[ derive( Debug , Deserialize , PartialEq ) ]
806+ #[ serde( untagged) ]
807+ pub enum AnyEnumDerive {
808+ String ( String ) ,
809+ Int ( u32 ) ,
810+ Other ,
811+ }
812+
813+ // single
814+ let rdef = ResourceDef :: new ( "/{key}" ) ;
815+
816+ let mut path = Path :: new ( "/%25" ) ;
817+ rdef. capture_match_info ( & mut path) ;
818+ let de = PathDeserializer :: new ( & path) ;
819+ let segment: AnyEnumCustom = serde:: Deserialize :: deserialize ( de) . unwrap ( ) ;
820+ assert_eq ! ( segment, AnyEnumCustom :: String ( "some str: %" . to_string( ) ) ) ;
821+
822+ let mut path = Path :: new ( "/%25" ) ;
823+ rdef. capture_match_info ( & mut path) ;
824+ let de = PathDeserializer :: new ( & path) ;
825+ let segment: AnyEnumDerive = serde:: Deserialize :: deserialize ( de) . unwrap ( ) ;
826+ assert_eq ! ( segment, AnyEnumDerive :: String ( "%" . to_string( ) ) ) ;
827+
828+ // seq
829+ let rdef = ResourceDef :: new ( "/{key}/{value}" ) ;
830+
831+ let mut path = Path :: new ( "/other/123" ) ;
832+ rdef. capture_match_info ( & mut path) ;
833+ let de = PathDeserializer :: new ( & path) ;
834+ let segment: ( AnyEnumCustom , AnyEnumDerive ) = serde:: Deserialize :: deserialize ( de) . unwrap ( ) ;
835+ assert_eq ! ( segment. 0 , AnyEnumCustom :: Other ) ;
836+ assert_eq ! ( segment. 1 , AnyEnumDerive :: Int ( 123 ) ) ;
837+
838+ // map
839+ #[ derive( Deserialize ) ]
840+ struct Vals {
841+ key : AnyEnumCustom ,
842+ value : AnyEnumDerive ,
843+ }
844+
845+ let rdef = ResourceDef :: new ( "/{key}/{value}" ) ;
846+
847+ let mut path = Path :: new ( "/123/%2F" ) ;
848+ rdef. capture_match_info ( & mut path) ;
849+ let de = PathDeserializer :: new ( & path) ;
850+ let vals: Vals = serde:: Deserialize :: deserialize ( de) . unwrap ( ) ;
851+ assert_eq ! ( vals. key, AnyEnumCustom :: Int ( 123 ) ) ;
852+ assert_eq ! ( vals. value, AnyEnumDerive :: String ( "/" . to_string( ) ) ) ;
853+ }
854+
707855 #[ test]
708856 fn deserialize_borrowed ( ) {
709857 #[ derive( Debug , Deserialize ) ]
0 commit comments