@@ -32,32 +32,66 @@ use super::raw::Decimal128Access;
32
32
33
33
pub ( crate ) struct BsonVisitor ;
34
34
35
- impl < ' de > Deserialize < ' de > for ObjectId {
36
- fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
35
+ struct ObjectIdVisitor ;
36
+
37
+ impl < ' de > Visitor < ' de > for ObjectIdVisitor {
38
+ type Value = ObjectId ;
39
+
40
+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
41
+ formatter. write_str ( "expecting an ObjectId" )
42
+ }
43
+
44
+ #[ inline]
45
+ fn visit_str < E > ( self , value : & str ) -> std:: result:: Result < Self :: Value , E >
37
46
where
38
- D : de :: Deserializer < ' de > ,
47
+ E : serde :: de :: Error ,
39
48
{
40
- #[ derive( serde:: Deserialize ) ]
41
- #[ serde( untagged) ]
42
- enum OidHelper {
43
- HexString ( String ) ,
44
- Bson ( Bson ) ,
49
+ ObjectId :: parse_str ( value) . map_err ( |_| {
50
+ E :: invalid_value (
51
+ Unexpected :: Str ( value) ,
52
+ & "24-character, big-endian hex string" ,
53
+ )
54
+ } )
55
+ }
56
+
57
+ #[ inline]
58
+ fn visit_bytes < E > ( self , v : & [ u8 ] ) -> std:: result:: Result < Self :: Value , E >
59
+ where
60
+ E : serde:: de:: Error ,
61
+ {
62
+ let bytes: [ u8 ; 12 ] = v
63
+ . try_into ( )
64
+ . map_err ( |_| E :: invalid_length ( v. len ( ) , & "12 bytes" ) ) ?;
65
+ Ok ( ObjectId :: from_bytes ( bytes) )
66
+ }
67
+
68
+ #[ inline]
69
+ fn visit_map < V > ( self , mut visitor : V ) -> Result < Self :: Value , V :: Error >
70
+ where
71
+ V : MapAccess < ' de > ,
72
+ {
73
+ match BsonVisitor . visit_map ( & mut visitor) ? {
74
+ Bson :: ObjectId ( oid) => Ok ( oid) ,
75
+ bson => {
76
+ let err = format ! (
77
+ "expected map containing extended-JSON formatted ObjectId, instead found {}" ,
78
+ bson
79
+ ) ;
80
+ Err ( de:: Error :: custom ( err) )
81
+ }
45
82
}
83
+ }
84
+ }
46
85
47
- match OidHelper :: deserialize ( deserializer)
48
- . map_err ( |_| de:: Error :: custom ( "expected ObjectId extended document or hex string" ) ) ?
49
- {
50
- OidHelper :: HexString ( s) => ObjectId :: parse_str ( & s) . map_err ( de:: Error :: custom) ,
51
- OidHelper :: Bson ( bson) => match bson {
52
- Bson :: ObjectId ( oid) => Ok ( oid) ,
53
- bson => {
54
- let err = format ! (
55
- "expected objectId extended document or hex string, found {}" ,
56
- bson
57
- ) ;
58
- Err ( de:: Error :: invalid_type ( Unexpected :: Map , & & err[ ..] ) )
59
- }
60
- } ,
86
+ impl < ' de > Deserialize < ' de > for ObjectId {
87
+ fn deserialize < D > ( deserializer : D ) -> std:: result:: Result < Self , D :: Error >
88
+ where
89
+ D : serde:: Deserializer < ' de > ,
90
+ {
91
+ if !deserializer. is_human_readable ( ) {
92
+ deserializer. deserialize_bytes ( ObjectIdVisitor )
93
+ } else {
94
+ deserializer. deserialize_any ( ObjectIdVisitor )
61
95
}
62
96
}
63
97
}
0 commit comments