@@ -41,27 +41,69 @@ pub mod webhooks {
4141/// Used with `#[serde(with = "optional_string")]`.
4242pub mod optional_string {
4343 use std:: fmt;
44+ use std:: marker:: PhantomData ;
45+ use std:: str:: FromStr ;
4446
4547 use serde:: de:: { Deserializer , Error , Visitor } ;
4648 use serde:: ser:: Serializer ;
4749
48- pub fn deserialize < ' de , D : Deserializer < ' de > > (
49- deserializer : D ,
50- ) -> Result < Option < u64 > , D :: Error > {
51- deserializer. deserialize_option ( OptionalStringVisitor )
50+ // Workaround for https://github.com/LPGhatguy/nonmax/issues/17
51+ pub ( crate ) trait TryFromU64
52+ where
53+ Self : Sized ,
54+ {
55+ type Err : fmt:: Display ;
56+ fn try_from_u64 ( value : u64 ) -> Result < Self , Self :: Err > ;
57+ }
58+
59+ impl TryFromU64 for u64 {
60+ type Err = std:: convert:: Infallible ;
61+ fn try_from_u64 ( value : u64 ) -> Result < Self , Self :: Err > {
62+ Ok ( value)
63+ }
64+ }
65+
66+ impl TryFromU64 for nonmax:: NonMaxU64 {
67+ type Err = nonmax:: TryFromIntError ;
68+ fn try_from_u64 ( value : u64 ) -> Result < Self , Self :: Err > {
69+ Self :: try_from ( value)
70+ }
71+ }
72+
73+ impl TryFromU64 for nonmax:: NonMaxU32 {
74+ type Err = nonmax:: TryFromIntError ;
75+ fn try_from_u64 ( value : u64 ) -> Result < Self , Self :: Err > {
76+ Self :: try_from ( u32:: try_from ( value) ?)
77+ }
78+ }
79+
80+ pub fn deserialize < ' de , D , T > ( deserializer : D ) -> Result < Option < T > , D :: Error >
81+ where
82+ D : Deserializer < ' de > ,
83+ T : FromStr + TryFromU64 ,
84+ <T as FromStr >:: Err : fmt:: Display ,
85+ {
86+ deserializer. deserialize_option ( OptionalStringVisitor :: < T > ( PhantomData ) )
5287 }
5388
54- pub fn serialize < S : Serializer > ( value : & Option < u64 > , serializer : S ) -> Result < S :: Ok , S :: Error > {
89+ pub fn serialize < S : Serializer > (
90+ value : & Option < impl ToString > ,
91+ serializer : S ,
92+ ) -> Result < S :: Ok , S :: Error > {
5593 match value {
5694 Some ( value) => serializer. serialize_some ( & value. to_string ( ) ) ,
5795 None => serializer. serialize_none ( ) ,
5896 }
5997 }
6098
61- struct OptionalStringVisitor ;
99+ struct OptionalStringVisitor < T > ( PhantomData < T > ) ;
62100
63- impl < ' de > Visitor < ' de > for OptionalStringVisitor {
64- type Value = Option < u64 > ;
101+ impl < ' de , T > Visitor < ' de > for OptionalStringVisitor < T >
102+ where
103+ T : FromStr + TryFromU64 ,
104+ <T as FromStr >:: Err : fmt:: Display ,
105+ {
106+ type Value = Option < T > ;
65107
66108 fn expecting ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
67109 formatter. write_str ( "an optional integer or a string with a valid number inside" )
@@ -71,7 +113,7 @@ pub mod optional_string {
71113 self ,
72114 deserializer : D ,
73115 ) -> Result < Self :: Value , D :: Error > {
74- deserializer. deserialize_any ( OptionalStringVisitor )
116+ deserializer. deserialize_any ( OptionalStringVisitor ( PhantomData ) )
75117 }
76118
77119 fn visit_none < E : Error > ( self ) -> Result < Self :: Value , E > {
@@ -83,11 +125,11 @@ pub mod optional_string {
83125 Ok ( None )
84126 }
85127
86- fn visit_u64 < E : Error > ( self , val : u64 ) -> Result < Option < u64 > , E > {
87- Ok ( Some ( val) )
128+ fn visit_u64 < E : Error > ( self , val : u64 ) -> Result < Self :: Value , E > {
129+ T :: try_from_u64 ( val) . map ( Some ) . map_err ( Error :: custom )
88130 }
89131
90- fn visit_str < E : Error > ( self , string : & str ) -> Result < Option < u64 > , E > {
132+ fn visit_str < E : Error > ( self , string : & str ) -> Result < Self :: Value , E > {
91133 string. parse ( ) . map ( Some ) . map_err ( Error :: custom)
92134 }
93135 }
0 commit comments