@@ -44,6 +44,160 @@ use super::{
44
44
/// A visitor used to deserialize types backed by raw BSON.
45
45
pub ( crate ) struct OwnedOrBorrowedRawBsonVisitor ;
46
46
47
+ pub ( super ) enum MapParse < ' de > {
48
+ Leaf ( OwnedOrBorrowedRawBson < ' de > ) ,
49
+ Aggregate ( CowStr < ' de > ) ,
50
+ }
51
+
52
+ impl OwnedOrBorrowedRawBsonVisitor {
53
+ pub ( super ) fn parse_map < ' de , A > ( map : & mut A ) -> Result < MapParse < ' de > , A :: Error >
54
+ where
55
+ A : serde:: de:: MapAccess < ' de > ,
56
+ {
57
+ let first_key = match map. next_key :: < CowStr > ( ) ? {
58
+ Some ( k) => k,
59
+ None => {
60
+ return Ok ( MapParse :: Leaf (
61
+ RawBson :: Document ( RawDocumentBuf :: new ( ) ) . into ( ) ,
62
+ ) )
63
+ }
64
+ } ;
65
+ Ok ( MapParse :: Leaf ( match first_key. 0 . as_ref ( ) {
66
+ "$oid" => {
67
+ let oid: ObjectId = map. next_value ( ) ?;
68
+ RawBsonRef :: ObjectId ( oid) . into ( )
69
+ }
70
+ "$symbol" => {
71
+ let s: CowStr = map. next_value ( ) ?;
72
+ match s. 0 {
73
+ Cow :: Borrowed ( s) => RawBsonRef :: Symbol ( s) . into ( ) ,
74
+ Cow :: Owned ( s) => RawBson :: Symbol ( s) . into ( ) ,
75
+ }
76
+ }
77
+ "$numberDecimalBytes" => {
78
+ let bytes: ByteBuf = map. next_value ( ) ?;
79
+ RawBsonRef :: Decimal128 ( Decimal128 :: deserialize_from_slice ( bytes. as_ref ( ) ) ?) . into ( )
80
+ }
81
+ "$regularExpression" => {
82
+ let body: BorrowedRegexBody = map. next_value ( ) ?;
83
+
84
+ match ( body. pattern , body. options ) {
85
+ ( Cow :: Borrowed ( p) , Cow :: Borrowed ( o) ) => {
86
+ RawBsonRef :: RegularExpression ( RawRegexRef {
87
+ pattern : p,
88
+ options : o,
89
+ } )
90
+ . into ( )
91
+ }
92
+ ( p, o) => RawBson :: RegularExpression ( Regex {
93
+ pattern : p. into_owned ( ) ,
94
+ options : o. into_owned ( ) ,
95
+ } )
96
+ . into ( ) ,
97
+ }
98
+ }
99
+ "$undefined" => {
100
+ let _: bool = map. next_value ( ) ?;
101
+ RawBsonRef :: Undefined . into ( )
102
+ }
103
+ "$binary" => {
104
+ let v: BorrowedBinaryBody = map. next_value ( ) ?;
105
+
106
+ if let Cow :: Borrowed ( bytes) = v. bytes {
107
+ RawBsonRef :: Binary ( RawBinaryRef {
108
+ bytes,
109
+ subtype : v. subtype . into ( ) ,
110
+ } )
111
+ . into ( )
112
+ } else {
113
+ RawBson :: Binary ( Binary {
114
+ bytes : v. bytes . into_owned ( ) ,
115
+ subtype : v. subtype . into ( ) ,
116
+ } )
117
+ . into ( )
118
+ }
119
+ }
120
+ "$date" => {
121
+ let date: i64 = map. next_value ( ) ?;
122
+ RawBsonRef :: DateTime ( DateTime :: from_millis ( date) ) . into ( )
123
+ }
124
+ "$timestamp" => {
125
+ let timestamp: TimestampBody = map. next_value ( ) ?;
126
+ RawBsonRef :: Timestamp ( Timestamp {
127
+ time : timestamp. t ,
128
+ increment : timestamp. i ,
129
+ } )
130
+ . into ( )
131
+ }
132
+ "$minKey" => {
133
+ let _ = map. next_value :: < i32 > ( ) ?;
134
+ RawBsonRef :: MinKey . into ( )
135
+ }
136
+ "$maxKey" => {
137
+ let _ = map. next_value :: < i32 > ( ) ?;
138
+ RawBsonRef :: MaxKey . into ( )
139
+ }
140
+ "$code" => {
141
+ let code = map. next_value :: < CowStr > ( ) ?;
142
+ if let Some ( key) = map. next_key :: < CowStr > ( ) ? {
143
+ if key. 0 . as_ref ( ) == "$scope" {
144
+ let scope = map. next_value :: < OwnedOrBorrowedRawDocument > ( ) ?;
145
+ match ( code. 0 , scope) {
146
+ ( Cow :: Borrowed ( code) , OwnedOrBorrowedRawDocument :: Borrowed ( scope) ) => {
147
+ RawBsonRef :: JavaScriptCodeWithScope ( RawJavaScriptCodeWithScopeRef {
148
+ code,
149
+ scope,
150
+ } )
151
+ . into ( )
152
+ }
153
+ ( code, scope) => {
154
+ RawBson :: JavaScriptCodeWithScope ( RawJavaScriptCodeWithScope {
155
+ code : code. into_owned ( ) ,
156
+ scope : scope. into_owned ( ) ,
157
+ } )
158
+ . into ( )
159
+ }
160
+ }
161
+ } else {
162
+ return Err ( SerdeError :: unknown_field ( & key. 0 , & [ "$scope" ] ) ) ;
163
+ }
164
+ } else if let Cow :: Borrowed ( code) = code. 0 {
165
+ RawBsonRef :: JavaScriptCode ( code) . into ( )
166
+ } else {
167
+ RawBson :: JavaScriptCode ( code. 0 . into_owned ( ) ) . into ( )
168
+ }
169
+ }
170
+ "$dbPointer" => {
171
+ let db_pointer: BorrowedDbPointerBody = map. next_value ( ) ?;
172
+ if let Cow :: Borrowed ( ns) = db_pointer. ns . 0 {
173
+ RawBsonRef :: DbPointer ( RawDbPointerRef {
174
+ namespace : ns,
175
+ id : db_pointer. id ,
176
+ } )
177
+ . into ( )
178
+ } else {
179
+ RawBson :: DbPointer ( DbPointer {
180
+ namespace : db_pointer. ns . 0 . into_owned ( ) ,
181
+ id : db_pointer. id ,
182
+ } )
183
+ . into ( )
184
+ }
185
+ }
186
+ RAW_DOCUMENT_NEWTYPE => {
187
+ let bson = map. next_value :: < & [ u8 ] > ( ) ?;
188
+ let doc = RawDocument :: from_bytes ( bson) . map_err ( SerdeError :: custom) ?;
189
+ RawBsonRef :: Document ( doc) . into ( )
190
+ }
191
+ RAW_ARRAY_NEWTYPE => {
192
+ let bson = map. next_value :: < & [ u8 ] > ( ) ?;
193
+ let doc = RawDocument :: from_bytes ( bson) . map_err ( SerdeError :: custom) ?;
194
+ RawBsonRef :: Array ( RawArray :: from_doc ( doc) ) . into ( )
195
+ }
196
+ _ => return Ok ( MapParse :: Aggregate ( first_key) ) ,
197
+ } ) )
198
+ }
199
+ }
200
+
47
201
impl < ' de > Visitor < ' de > for OwnedOrBorrowedRawBsonVisitor {
48
202
type Value = OwnedOrBorrowedRawBson < ' de > ;
49
203
@@ -209,145 +363,9 @@ impl<'de> Visitor<'de> for OwnedOrBorrowedRawBsonVisitor {
209
363
where
210
364
A : serde:: de:: MapAccess < ' de > ,
211
365
{
212
- let first_key = match map. next_key :: < CowStr > ( ) ? {
213
- Some ( k) => k,
214
- None => return Ok ( RawBson :: Document ( RawDocumentBuf :: new ( ) ) . into ( ) ) ,
215
- } ;
216
-
217
- match first_key. 0 . as_ref ( ) {
218
- "$oid" => {
219
- let oid: ObjectId = map. next_value ( ) ?;
220
- Ok ( RawBsonRef :: ObjectId ( oid) . into ( ) )
221
- }
222
- "$symbol" => {
223
- let s: CowStr = map. next_value ( ) ?;
224
- match s. 0 {
225
- Cow :: Borrowed ( s) => Ok ( RawBsonRef :: Symbol ( s) . into ( ) ) ,
226
- Cow :: Owned ( s) => Ok ( RawBson :: Symbol ( s) . into ( ) ) ,
227
- }
228
- }
229
- "$numberDecimalBytes" => {
230
- let bytes: ByteBuf = map. next_value ( ) ?;
231
- return Ok ( RawBsonRef :: Decimal128 ( Decimal128 :: deserialize_from_slice (
232
- bytes. as_ref ( ) ,
233
- ) ?)
234
- . into ( ) ) ;
235
- }
236
- "$regularExpression" => {
237
- let body: BorrowedRegexBody = map. next_value ( ) ?;
238
-
239
- match ( body. pattern , body. options ) {
240
- ( Cow :: Borrowed ( p) , Cow :: Borrowed ( o) ) => {
241
- Ok ( RawBsonRef :: RegularExpression ( RawRegexRef {
242
- pattern : p,
243
- options : o,
244
- } )
245
- . into ( ) )
246
- }
247
- ( p, o) => Ok ( RawBson :: RegularExpression ( Regex {
248
- pattern : p. into_owned ( ) ,
249
- options : o. into_owned ( ) ,
250
- } )
251
- . into ( ) ) ,
252
- }
253
- }
254
- "$undefined" => {
255
- let _: bool = map. next_value ( ) ?;
256
- Ok ( RawBsonRef :: Undefined . into ( ) )
257
- }
258
- "$binary" => {
259
- let v: BorrowedBinaryBody = map. next_value ( ) ?;
260
-
261
- if let Cow :: Borrowed ( bytes) = v. bytes {
262
- Ok ( RawBsonRef :: Binary ( RawBinaryRef {
263
- bytes,
264
- subtype : v. subtype . into ( ) ,
265
- } )
266
- . into ( ) )
267
- } else {
268
- Ok ( RawBson :: Binary ( Binary {
269
- bytes : v. bytes . into_owned ( ) ,
270
- subtype : v. subtype . into ( ) ,
271
- } )
272
- . into ( ) )
273
- }
274
- }
275
- "$date" => {
276
- let date: i64 = map. next_value ( ) ?;
277
- Ok ( RawBsonRef :: DateTime ( DateTime :: from_millis ( date) ) . into ( ) )
278
- }
279
- "$timestamp" => {
280
- let timestamp: TimestampBody = map. next_value ( ) ?;
281
- Ok ( RawBsonRef :: Timestamp ( Timestamp {
282
- time : timestamp. t ,
283
- increment : timestamp. i ,
284
- } )
285
- . into ( ) )
286
- }
287
- "$minKey" => {
288
- let _ = map. next_value :: < i32 > ( ) ?;
289
- Ok ( RawBsonRef :: MinKey . into ( ) )
290
- }
291
- "$maxKey" => {
292
- let _ = map. next_value :: < i32 > ( ) ?;
293
- Ok ( RawBsonRef :: MaxKey . into ( ) )
294
- }
295
- "$code" => {
296
- let code = map. next_value :: < CowStr > ( ) ?;
297
- if let Some ( key) = map. next_key :: < CowStr > ( ) ? {
298
- if key. 0 . as_ref ( ) == "$scope" {
299
- let scope = map. next_value :: < OwnedOrBorrowedRawDocument > ( ) ?;
300
- match ( code. 0 , scope) {
301
- ( Cow :: Borrowed ( code) , OwnedOrBorrowedRawDocument :: Borrowed ( scope) ) => {
302
- Ok ( RawBsonRef :: JavaScriptCodeWithScope (
303
- RawJavaScriptCodeWithScopeRef { code, scope } ,
304
- )
305
- . into ( ) )
306
- }
307
- ( code, scope) => Ok ( RawBson :: JavaScriptCodeWithScope (
308
- RawJavaScriptCodeWithScope {
309
- code : code. into_owned ( ) ,
310
- scope : scope. into_owned ( ) ,
311
- } ,
312
- )
313
- . into ( ) ) ,
314
- }
315
- } else {
316
- Err ( SerdeError :: unknown_field ( & key. 0 , & [ "$scope" ] ) )
317
- }
318
- } else if let Cow :: Borrowed ( code) = code. 0 {
319
- Ok ( RawBsonRef :: JavaScriptCode ( code) . into ( ) )
320
- } else {
321
- Ok ( RawBson :: JavaScriptCode ( code. 0 . into_owned ( ) ) . into ( ) )
322
- }
323
- }
324
- "$dbPointer" => {
325
- let db_pointer: BorrowedDbPointerBody = map. next_value ( ) ?;
326
- if let Cow :: Borrowed ( ns) = db_pointer. ns . 0 {
327
- Ok ( RawBsonRef :: DbPointer ( RawDbPointerRef {
328
- namespace : ns,
329
- id : db_pointer. id ,
330
- } )
331
- . into ( ) )
332
- } else {
333
- Ok ( RawBson :: DbPointer ( DbPointer {
334
- namespace : db_pointer. ns . 0 . into_owned ( ) ,
335
- id : db_pointer. id ,
336
- } )
337
- . into ( ) )
338
- }
339
- }
340
- RAW_DOCUMENT_NEWTYPE => {
341
- let bson = map. next_value :: < & [ u8 ] > ( ) ?;
342
- let doc = RawDocument :: from_bytes ( bson) . map_err ( SerdeError :: custom) ?;
343
- Ok ( RawBsonRef :: Document ( doc) . into ( ) )
344
- }
345
- RAW_ARRAY_NEWTYPE => {
346
- let bson = map. next_value :: < & [ u8 ] > ( ) ?;
347
- let doc = RawDocument :: from_bytes ( bson) . map_err ( SerdeError :: custom) ?;
348
- Ok ( RawBsonRef :: Array ( RawArray :: from_doc ( doc) ) . into ( ) )
349
- }
350
- _ => {
366
+ match Self :: parse_map ( & mut map) ? {
367
+ MapParse :: Leaf ( value) => Ok ( value) ,
368
+ MapParse :: Aggregate ( first_key) => {
351
369
let mut buffer = CowByteBuffer :: new ( ) ;
352
370
let seeded_visitor = SeededVisitor :: new ( & mut buffer) ;
353
371
seeded_visitor. iterate_map ( first_key, map) ?;
0 commit comments