@@ -123,9 +123,7 @@ pub fn decode_document<R: Read + ?Sized>(reader: &mut R) -> DecoderResult<Docume
123
123
break ;
124
124
}
125
125
126
- let key = read_cstring ( reader) ?;
127
- let val = decode_bson ( reader, tag, false ) ?;
128
-
126
+ let ( key, val) = decode_bson_kvp ( reader, tag, false ) ?;
129
127
doc. insert ( key, val) ;
130
128
}
131
129
@@ -146,8 +144,7 @@ pub fn decode_document_utf8_lossy<R: Read + ?Sized>(reader: &mut R) -> DecoderRe
146
144
break ;
147
145
}
148
146
149
- let key = read_cstring ( reader) ?;
150
- let val = decode_bson ( reader, tag, true ) ?;
147
+ let ( key, val) = decode_bson_kvp ( reader, tag, true ) ?;
151
148
152
149
doc. insert ( key, val) ;
153
150
}
@@ -167,8 +164,7 @@ fn decode_array<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> DecoderRe
167
164
break ;
168
165
}
169
166
170
- // check that the key is as expected
171
- let key = read_cstring ( reader) ?;
167
+ let ( key, val) = decode_bson_kvp ( reader, tag, utf8_lossy) ?;
172
168
match key. parse :: < usize > ( ) {
173
169
Err ( ..) => return Err ( DecoderError :: InvalidArrayKey ( arr. len ( ) , key) ) ,
174
170
Ok ( idx) => {
@@ -177,24 +173,25 @@ fn decode_array<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> DecoderRe
177
173
}
178
174
}
179
175
}
180
-
181
- let val = decode_bson ( reader, tag, utf8_lossy) ?;
182
176
arr. push ( val)
183
177
}
184
178
185
179
Ok ( arr)
186
180
}
187
181
188
- fn decode_bson < R : Read + ?Sized > ( reader : & mut R , tag : u8 , utf8_lossy : bool ) -> DecoderResult < Bson > {
182
+ fn decode_bson_kvp < R : Read + ?Sized > (
183
+ reader : & mut R ,
184
+ tag : u8 ,
185
+ utf8_lossy : bool ,
186
+ ) -> DecoderResult < ( String , Bson ) > {
189
187
use spec:: ElementType ;
188
+ let key = read_cstring ( reader) ?;
190
189
191
- match ElementType :: from ( tag) {
192
- Some ( ElementType :: FloatingPoint ) => {
193
- Ok ( Bson :: FloatingPoint ( reader. read_f64 :: < LittleEndian > ( ) ?) )
194
- }
195
- Some ( ElementType :: Utf8String ) => read_string ( reader, utf8_lossy) . map ( Bson :: String ) ,
196
- Some ( ElementType :: EmbeddedDocument ) => decode_document ( reader) . map ( Bson :: Document ) ,
197
- Some ( ElementType :: Array ) => decode_array ( reader, utf8_lossy) . map ( Bson :: Array ) ,
190
+ let val = match ElementType :: from ( tag) {
191
+ Some ( ElementType :: FloatingPoint ) => Bson :: FloatingPoint ( reader. read_f64 :: < LittleEndian > ( ) ?) ,
192
+ Some ( ElementType :: Utf8String ) => read_string ( reader, utf8_lossy) . map ( Bson :: String ) ?,
193
+ Some ( ElementType :: EmbeddedDocument ) => decode_document ( reader) . map ( Bson :: Document ) ?,
194
+ Some ( ElementType :: Array ) => decode_array ( reader, utf8_lossy) . map ( Bson :: Array ) ?,
198
195
Some ( ElementType :: Binary ) => {
199
196
let len = read_i32 ( reader) ?;
200
197
if len < 0 || len > MAX_BSON_SIZE {
@@ -206,24 +203,24 @@ fn decode_bson<R: Read + ?Sized>(reader: &mut R, tag: u8, utf8_lossy: bool) -> D
206
203
let subtype = BinarySubtype :: from ( reader. read_u8 ( ) ?) ;
207
204
let mut bytes = Vec :: with_capacity ( len as usize ) ;
208
205
reader. take ( len as u64 ) . read_to_end ( & mut bytes) ?;
209
- Ok ( Bson :: Binary ( Binary { subtype, bytes } ) )
206
+ Bson :: Binary ( Binary { subtype, bytes } )
210
207
}
211
208
Some ( ElementType :: ObjectId ) => {
212
209
let mut objid = [ 0 ; 12 ] ;
213
210
for x in & mut objid {
214
211
* x = reader. read_u8 ( ) ?;
215
212
}
216
- Ok ( Bson :: ObjectId ( oid:: ObjectId :: with_bytes ( objid) ) )
213
+ Bson :: ObjectId ( oid:: ObjectId :: with_bytes ( objid) )
217
214
}
218
- Some ( ElementType :: Boolean ) => Ok ( Bson :: Boolean ( reader. read_u8 ( ) ? != 0 ) ) ,
219
- Some ( ElementType :: NullValue ) => Ok ( Bson :: Null ) ,
215
+ Some ( ElementType :: Boolean ) => Bson :: Boolean ( reader. read_u8 ( ) ? != 0 ) ,
216
+ Some ( ElementType :: NullValue ) => Bson :: Null ,
220
217
Some ( ElementType :: RegularExpression ) => {
221
218
let pattern = read_cstring ( reader) ?;
222
219
let options = read_cstring ( reader) ?;
223
- Ok ( Bson :: Regex ( Regex { pattern, options } ) )
220
+ Bson :: Regex ( Regex { pattern, options } )
224
221
}
225
222
Some ( ElementType :: JavaScriptCode ) => {
226
- read_string ( reader, utf8_lossy) . map ( Bson :: JavaScriptCode )
223
+ read_string ( reader, utf8_lossy) . map ( Bson :: JavaScriptCode ) ?
227
224
}
228
225
Some ( ElementType :: JavaScriptCodeWithScope ) => {
229
226
// disregard the length:
@@ -232,15 +229,12 @@ fn decode_bson<R: Read + ?Sized>(reader: &mut R, tag: u8, utf8_lossy: bool) -> D
232
229
233
230
let code = read_string ( reader, utf8_lossy) ?;
234
231
let scope = decode_document ( reader) ?;
235
- Ok ( Bson :: JavaScriptCodeWithScope ( JavaScriptCodeWithScope {
236
- code,
237
- scope,
238
- } ) )
232
+ Bson :: JavaScriptCodeWithScope ( JavaScriptCodeWithScope { code, scope } )
239
233
}
240
- Some ( ElementType :: Integer32Bit ) => read_i32 ( reader) . map ( Bson :: I32 ) ,
241
- Some ( ElementType :: Integer64Bit ) => read_i64 ( reader) . map ( Bson :: I64 ) ,
234
+ Some ( ElementType :: Integer32Bit ) => read_i32 ( reader) . map ( Bson :: I32 ) ? ,
235
+ Some ( ElementType :: Integer64Bit ) => read_i64 ( reader) . map ( Bson :: I64 ) ? ,
242
236
Some ( ElementType :: TimeStamp ) => {
243
- read_i64 ( reader) . map ( |val| Bson :: TimeStamp ( TimeStamp :: from_le_i64 ( val) ) )
237
+ read_i64 ( reader) . map ( |val| Bson :: TimeStamp ( TimeStamp :: from_le_i64 ( val) ) ) ?
244
238
}
245
239
Some ( ElementType :: UtcDatetime ) => {
246
240
// The int64 is UTC milliseconds since the Unix epoch.
@@ -255,28 +249,35 @@ fn decode_bson<R: Read + ?Sized>(reader: &mut R, tag: u8, utf8_lossy: bool) -> D
255
249
} ;
256
250
257
251
match Utc . timestamp_opt ( sec, ( msec as u32 ) * 1_000_000 ) {
258
- LocalResult :: None => Err ( DecoderError :: InvalidTimestamp ( time) ) ,
259
- LocalResult :: Ambiguous ( ..) => Err ( DecoderError :: AmbiguousTimestamp ( time) ) ,
260
- LocalResult :: Single ( t) => Ok ( Bson :: UtcDatetime ( t) ) ,
252
+ LocalResult :: None => return Err ( DecoderError :: InvalidTimestamp ( time) ) ,
253
+ LocalResult :: Ambiguous ( ..) => return Err ( DecoderError :: AmbiguousTimestamp ( time) ) ,
254
+ LocalResult :: Single ( t) => Bson :: UtcDatetime ( t) ,
261
255
}
262
256
}
263
- Some ( ElementType :: Symbol ) => read_string ( reader, utf8_lossy) . map ( Bson :: Symbol ) ,
257
+ Some ( ElementType :: Symbol ) => read_string ( reader, utf8_lossy) . map ( Bson :: Symbol ) ? ,
264
258
#[ cfg( feature = "decimal128" ) ]
265
- Some ( ElementType :: Decimal128Bit ) => read_f128 ( reader) . map ( Bson :: Decimal128 ) ,
266
- Some ( ElementType :: Undefined ) => Ok ( Bson :: Undefined ) ,
259
+ Some ( ElementType :: Decimal128Bit ) => read_f128 ( reader) . map ( Bson :: Decimal128 ) ? ,
260
+ Some ( ElementType :: Undefined ) => Bson :: Undefined ,
267
261
Some ( ElementType :: DbPointer ) => {
268
262
let namespace = read_string ( reader, utf8_lossy) ?;
269
263
let mut objid = [ 0 ; 12 ] ;
270
264
reader. read_exact ( & mut objid) ?;
271
- Ok ( Bson :: DbPointer ( DbPointer {
265
+ Bson :: DbPointer ( DbPointer {
272
266
namespace,
273
267
id : oid:: ObjectId :: with_bytes ( objid) ,
274
- } ) )
268
+ } )
275
269
}
276
- Some ( ElementType :: MaxKey ) => Ok ( Bson :: MaxKey ) ,
277
- Some ( ElementType :: MinKey ) => Ok ( Bson :: MinKey ) ,
278
- None => Err ( DecoderError :: UnrecognizedElementType ( tag) ) ,
279
- }
270
+ Some ( ElementType :: MaxKey ) => Bson :: MaxKey ,
271
+ Some ( ElementType :: MinKey ) => Bson :: MinKey ,
272
+ None => {
273
+ return Err ( DecoderError :: UnrecognizedDocumentElementType {
274
+ key,
275
+ element_type : tag,
276
+ } )
277
+ }
278
+ } ;
279
+
280
+ Ok ( ( key, val) )
280
281
}
281
282
282
283
/// Decode a BSON `Value` into a `T` Deserializable.
0 commit comments