@@ -722,6 +722,104 @@ mod tests {
722722 assert_eq ! ( vals. value, "/" ) ;
723723 }
724724
725+ #[ test]
726+ fn deserialize_path_decode_any ( ) {
727+ #[ derive( Debug , PartialEq ) ]
728+ pub enum AnyEnumCustom {
729+ String ( String ) ,
730+ Int ( u32 ) ,
731+ Other ,
732+ }
733+
734+ impl < ' de > Deserialize < ' de > for AnyEnumCustom {
735+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
736+ where
737+ D : serde:: Deserializer < ' de > ,
738+ {
739+ struct Vis ;
740+ impl < ' de > Visitor < ' de > for Vis {
741+ type Value = AnyEnumCustom ;
742+
743+ fn expecting < ' a > (
744+ & self ,
745+ f : & mut std:: fmt:: Formatter < ' a > ,
746+ ) -> std:: fmt:: Result {
747+ write ! ( f, "my thing" )
748+ }
749+
750+ fn visit_u32 < E > ( self , v : u32 ) -> Result < Self :: Value , E >
751+ where
752+ E : serde:: de:: Error ,
753+ {
754+ Ok ( AnyEnumCustom :: Int ( v) )
755+ }
756+
757+ fn visit_str < E : serde:: de:: Error > ( self , v : & str ) -> Result < Self :: Value , E > {
758+ v. parse ( ) . map ( AnyEnumCustom :: Int ) . or_else ( |_| {
759+ Ok ( match v {
760+ "other" => AnyEnumCustom :: Other ,
761+ _ => AnyEnumCustom :: String ( format ! ( "some str: {v}" ) ) ,
762+ } )
763+ } )
764+ }
765+ }
766+
767+ deserializer. deserialize_any ( Vis )
768+ }
769+ }
770+
771+ #[ derive( Debug , Deserialize , PartialEq ) ]
772+ #[ serde( untagged) ]
773+ pub enum AnyEnumDerive {
774+ String ( String ) ,
775+ Int ( u32 ) ,
776+ Other ,
777+ }
778+
779+ // single
780+ let rdef = ResourceDef :: new ( "/{key}" ) ;
781+
782+ let mut path = Path :: new ( "/%25" ) ;
783+ rdef. capture_match_info ( & mut path) ;
784+ let de = PathDeserializer :: new ( & path) ;
785+ let segment: AnyEnumCustom = serde:: Deserialize :: deserialize ( de) . unwrap ( ) ;
786+ assert_eq ! ( segment, AnyEnumCustom :: String ( "some str: %" . to_string( ) ) ) ;
787+
788+ let mut path = Path :: new ( "/%25" ) ;
789+ rdef. capture_match_info ( & mut path) ;
790+ let de = PathDeserializer :: new ( & path) ;
791+ let segment: AnyEnumDerive = serde:: Deserialize :: deserialize ( de) . unwrap ( ) ;
792+ assert_eq ! ( segment, AnyEnumDerive :: String ( "%" . to_string( ) ) ) ;
793+
794+ // seq
795+ let rdef = ResourceDef :: new ( "/{key}/{value}" ) ;
796+
797+ let mut path = Path :: new ( "/other/123" ) ;
798+ rdef. capture_match_info ( & mut path) ;
799+ let de = PathDeserializer :: new ( & path) ;
800+ let segment: ( AnyEnumCustom , AnyEnumDerive ) =
801+ serde:: Deserialize :: deserialize ( de) . unwrap ( ) ;
802+ assert_eq ! ( segment. 0 , AnyEnumCustom :: Other ) ;
803+ // Deserializes to `String` instead of `Int` because deserializing defaults to `str` and serde doesn't automatically implement parsing numbers from `&str`s
804+ assert_eq ! ( segment. 1 , AnyEnumDerive :: String ( "123" . to_string( ) ) ) ;
805+
806+ // map
807+ #[ derive( Deserialize ) ]
808+ struct Vals {
809+ key : AnyEnumCustom ,
810+ value : AnyEnumDerive ,
811+ }
812+
813+ let rdef = ResourceDef :: new ( "/{key}/{value}" ) ;
814+
815+ let mut path = Path :: new ( "/123/%2F" ) ;
816+ rdef. capture_match_info ( & mut path) ;
817+ let de = PathDeserializer :: new ( & path) ;
818+ let vals: Vals = serde:: Deserialize :: deserialize ( de) . unwrap ( ) ;
819+ assert_eq ! ( vals. key, AnyEnumCustom :: Int ( 123 ) ) ;
820+ assert_eq ! ( vals. value, AnyEnumDerive :: String ( "/" . to_string( ) ) ) ;
821+ }
822+
725823 #[ test]
726824 fn deserialize_borrowed ( ) {
727825 #[ derive( Debug , Deserialize ) ]
0 commit comments