Skip to content

Commit 523a113

Browse files
committed
Use Extended JSON for conversion methods
1 parent 5dcf338 commit 523a113

File tree

3 files changed

+52
-20
lines changed

3 files changed

+52
-20
lines changed

src/bson.rs

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,19 @@ impl Bson {
245245
&Bson::Null => json::Json::Null,
246246
&Bson::RegExp(ref pat, ref opt) => {
247247
let mut re = json::Object::new();
248-
re.insert("pattern".to_owned(), json::Json::String(pat.clone()));
249-
re.insert("options".to_owned(), json::Json::String(opt.clone()));
248+
re.insert("$regex".to_owned(), json::Json::String(pat.clone()));
249+
re.insert("$options".to_owned(), json::Json::String(opt.clone()));
250250

251251
json::Json::Object(re)
252252
},
253-
&Bson::JavaScriptCode(ref code) => json::Json::String(code.clone()),
253+
&Bson::JavaScriptCode(ref code) => {
254+
let mut obj = json::Object::new();
255+
obj.insert("$code".to_owned(), json::Json::String(code.clone()));
256+
json::Json::Object(obj)
257+
},
254258
&Bson::JavaScriptCodeWithScope(ref code, ref scope) => {
255259
let mut obj = json::Object::new();
256-
obj.insert("code".to_owned(), json::Json::String(code.clone()));
260+
obj.insert("$code".to_owned(), json::Json::String(code.clone()));
257261

258262
let scope_obj =
259263
scope.iter().map(|(k, v)| (k.clone(), v.to_json())).collect();
@@ -264,17 +268,38 @@ impl Bson {
264268
},
265269
&Bson::I32(v) => json::Json::I64(v as i64),
266270
&Bson::I64(v) => json::Json::I64(v),
267-
&Bson::TimeStamp(v) => json::Json::I64(v),
271+
&Bson::TimeStamp(v) => {
272+
let time = v >> 32;
273+
let inc = v & 0x0000FFFF;
274+
275+
let mut obj = json::Object::new();
276+
obj.insert("t".to_owned(), json::Json::I64(time));
277+
obj.insert("i".to_owned(), json::Json::I64(inc));
278+
279+
json::Json::Object(obj)
280+
},
268281
&Bson::Binary(t, ref v) => {
269282
let mut obj = json::Object::new();
270283
let tval: u8 = From::from(t);
271284
obj.insert("type".to_owned(), json::Json::I64(tval as i64));
272-
obj.insert("data".to_owned(), json::Json::String(v.to_hex()));
285+
obj.insert("$binary".to_owned(), json::Json::String(v.to_hex()));
273286

274287
json::Json::Object(obj)
275288
},
276-
&Bson::ObjectId(ref v) => json::Json::String(v.bytes().to_hex()),
277-
&Bson::UtcDatetime(ref v) => json::Json::String(v.to_string()),
289+
&Bson::ObjectId(ref v) => {
290+
let mut obj = json::Object::new();
291+
obj.insert("$oid".to_owned(), json::Json::String(v.to_string()));
292+
293+
json::Json::Object(obj)
294+
},
295+
&Bson::UtcDatetime(ref v) => {
296+
let mut obj = json::Object::new();
297+
let mut inner = json::Object::new();
298+
inner.insert("$numberLong".to_owned(), json::Json::I64((v.timestamp() * 1000) +
299+
(v.nanosecond() / 1000000) as i64));
300+
obj.insert("$date".to_owned(), json::Json::Object(inner));
301+
json::Json::Object(obj)
302+
}
278303
}
279304
}
280305

@@ -287,7 +312,8 @@ impl Bson {
287312
&json::Json::String(ref x) => Bson::String(x.clone()),
288313
&json::Json::Boolean(x) => Bson::Boolean(x),
289314
&json::Json::Array(ref x) => Bson::Array(x.iter().map(Bson::from_json).collect()),
290-
&json::Json::Object(ref x) => Bson::Document(x.iter().map(|(k, v)| (k.clone(), Bson::from_json(v))).collect()),
315+
&json::Json::Object(ref x) => Bson::from_extended_document(
316+
x.iter().map(|(k, v)| (k.clone(), Bson::from_json(v))).collect()),
291317
&json::Json::Null => Bson::Null,
292318
}
293319
}
@@ -344,42 +370,48 @@ impl Bson {
344370
}
345371
}
346372

347-
pub fn from_extended_document(values: Document) -> Result<Bson, Error> {
373+
pub fn from_extended_document(values: Document) -> Bson {
348374
if values.contains_key("$regex") {
349375
if let Some(&Bson::String(ref pat)) = values.get("$regex") {
350376
if let Some(&Bson::String(ref opt)) = values.get("$options") {
351-
return Ok(Bson::RegExp(pat.to_owned(), opt.to_owned()));
377+
return Bson::RegExp(pat.to_owned(), opt.to_owned());
352378
}
353379
}
354380

355381
} else if let Some(&Bson::String(ref code)) = values.get("$code") {
356382
if let Some(&Bson::Document(ref scope)) = values.get("$scope") {
357-
return Ok(Bson::JavaScriptCodeWithScope(code.to_owned(), scope.to_owned()));
383+
return Bson::JavaScriptCodeWithScope(code.to_owned(), scope.to_owned());
358384
} else {
359-
return Ok(Bson::JavaScriptCode(code.to_owned()));
385+
return Bson::JavaScriptCode(code.to_owned());
360386
}
361387

362388
} else if let Some(&Bson::I32(t)) = values.get("t") {
363389
if let Some(&Bson::I32(i)) = values.get("i") {
364390
let timestamp = ((t as i64) << 32) + (i as i64);
365-
return Ok(Bson::TimeStamp(timestamp))
391+
return Bson::TimeStamp(timestamp)
392+
}
393+
394+
} else if let Some(&Bson::I64(t)) = values.get("t") {
395+
if let Some(&Bson::I64(i)) = values.get("i") {
396+
let timestamp = (t << 32) + i;
397+
return Bson::TimeStamp(timestamp)
366398
}
367399

368400
} else if let Some(&Bson::String(ref hex)) = values.get("$binary") {
369401
if let Some(&Bson::I64(t)) = values.get("type") {
370402
let ttype = t as u8;
371-
return Ok(Bson::Binary(From::from(ttype), hex.from_hex().unwrap()));
403+
return Bson::Binary(From::from(ttype), hex.from_hex().unwrap());
372404
}
373405

374406
} else if let Some(&Bson::String(ref hex)) = values.get("$oid") {
375-
return Ok(Bson::ObjectId(oid::ObjectId::with_string(hex).unwrap()));
407+
return Bson::ObjectId(oid::ObjectId::with_string(hex).unwrap());
376408

377409
} else if let Some(&Bson::Document(ref doc)) = values.get("$date") {
378410
if let Some(&Bson::I64(long)) = doc.get("$numberLong") {
379-
return Ok(Bson::UtcDatetime(UTC.timestamp(long / 1000, (long % 1000) as u32 * 1000000)));
411+
return Bson::UtcDatetime(UTC.timestamp(long / 1000, (long % 1000) as u32 * 1000000));
380412
}
381413
}
382414

383-
Ok(Bson::Document(values))
415+
Bson::Document(values)
384416
}
385417
}

src/decoder/serde.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl Visitor for BsonVisitor {
9292
where V: MapVisitor,
9393
{
9494
let values = try!(de::impls::BTreeMapVisitor::new().visit_map(visitor));
95-
Ok(Bson::from_extended_document(values.into()).unwrap())
95+
Ok(Bson::from_extended_document(values.into()))
9696
}
9797
}
9898

src/encoder/serde.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ impl Serializer for Encoder {
259259
state => panic!("expected object, found {:?}", state),
260260
};
261261

262-
let bson = Bson::from_extended_document(values).unwrap();
262+
let bson = Bson::from_extended_document(values);
263263

264264
self.state.push(State::Bson(bson));
265265
Ok(())

0 commit comments

Comments
 (0)