@@ -298,6 +298,58 @@ where
298298 deserializer. deserialize_any ( DeserializeEmptyArrayOrHashMapVisitor :: < K , V > ( PhantomData ) )
299299}
300300
301+ pub fn deserialize_u64_or_none < ' de , D > ( deserializer : D ) -> Result < Option < u64 > , D :: Error >
302+ where
303+ D : Deserializer < ' de > ,
304+ {
305+ deserializer. deserialize_any ( DeserializeU64OrNoneVisitor )
306+ }
307+
308+ pub struct DeserializeU64OrNoneVisitor ;
309+
310+ impl de:: Visitor < ' _ > for DeserializeU64OrNoneVisitor {
311+ type Value = Option < u64 > ;
312+
313+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
314+ formatter. write_str ( "u64, -1, false, or null" )
315+ }
316+
317+ fn visit_u64 < E > ( self , v : u64 ) -> Result < Self :: Value , E >
318+ where
319+ E : de:: Error ,
320+ {
321+ Ok ( Some ( v) )
322+ }
323+
324+ fn visit_i64 < E > ( self , v : i64 ) -> Result < Self :: Value , E >
325+ where
326+ E : de:: Error ,
327+ {
328+ if v == -1 {
329+ return Ok ( None ) ;
330+ }
331+
332+ return Err ( E :: invalid_value ( Unexpected :: Signed ( v) , & self ) )
333+ }
334+
335+ fn visit_bool < E > ( self , v : bool ) -> Result < Self :: Value , E >
336+ where
337+ E : de:: Error , {
338+ if !v {
339+ return Ok ( None ) ;
340+ }
341+
342+ return Err ( E :: invalid_value ( Unexpected :: Bool ( v) , & self ) )
343+ }
344+
345+ fn visit_unit < E > ( self ) -> Result < Self :: Value , E >
346+ where
347+ E : de:: Error , {
348+ Ok ( None )
349+ }
350+ }
351+
352+
301353#[ cfg( test) ]
302354mod tests {
303355 use super :: * ;
@@ -388,4 +440,20 @@ mod tests {
388440 serde_json:: from_str ( test_case) . expect ( "Test case should be a valid JSON" ) ;
389441 assert_eq ! ( expected_result, wrapper. map) ;
390442 }
443+
444+ #[ derive( Debug , Deserialize ) ]
445+ pub struct EmptyUIntOrEmpty {
446+ #[ serde( deserialize_with = "deserialize_u64_or_none" ) ]
447+ pub value : Option < u64 > ,
448+ }
449+
450+ #[ rstest]
451+ #[ case( r#"{"value": 1}"# , Some ( 1 ) ) ]
452+ #[ case( r#"{"value": null}"# , None ) ]
453+ #[ case( r#"{"value": -1}"# , None ) ]
454+ fn test_deserialize_empty_uint_or_empty ( #[ case] test_case : & str , #[ case] expected_result : Option < u64 > ) {
455+ let empty_uint_or_empty: EmptyUIntOrEmpty = serde_json:: from_str ( test_case) . expect ( "Test case should be a valid JSON" ) ;
456+ assert_eq ! ( expected_result, empty_uint_or_empty. value) ;
457+ }
458+
391459}
0 commit comments