1use std::{
25 convert::{TryFrom, TryInto},
26 fmt::{self, Debug, Display, Formatter},
27};
28
29use chrono::Datelike;
30use serde_json::{json, Value};
31
32pub use crate::document::Document;
33use crate::{
34 oid::{self, ObjectId},
35 spec::{BinarySubtype, ElementType},
36 Decimal128,
37};
38
39#[derive(Clone, PartialEq)]
41pub enum Bson {
42 Double(f64),
44 String(String),
46 Array(Array),
48 Document(Document),
50 Boolean(bool),
52 Null,
54 Int32(i32),
56 Int64(i64),
58 UInt32(u32),
60 UInt64(u64),
62 Timestamp(Timestamp),
64 Binary(Binary),
66 DateTime(crate::DateTime),
68 Decimal128(Decimal128),
70}
71
72pub type Array = Vec<Bson>;
74
75impl Default for Bson {
76 fn default() -> Self {
77 Bson::Null
78 }
79}
80
81impl Display for Bson {
82 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
83 match *self {
84 Bson::Double(f) => write!(fmt, "{}", f),
85 Bson::String(ref s) => write!(fmt, "\"{}\"", s),
86 Bson::Array(ref vec) => {
87 fmt.write_str("[")?;
88
89 let mut first = true;
90 for bson in vec {
91 if !first {
92 fmt.write_str(", ")?;
93 }
94
95 write!(fmt, "{}", bson)?;
96 first = false;
97 }
98
99 fmt.write_str("]")
100 }
101 Bson::Document(ref doc) => write!(fmt, "{}", doc),
102 Bson::Boolean(b) => write!(fmt, "{}", b),
103 Bson::Null => write!(fmt, "null"),
104 Bson::Int32(i) => write!(fmt, "{}", i),
105 Bson::Int64(i) => write!(fmt, "{}", i),
106 Bson::UInt32(i) => write!(fmt, "{}", i),
107 Bson::UInt64(i) => write!(fmt, "{}", i),
108 Bson::Timestamp(ref x) => write!(fmt, "{}", x),
109 Bson::Binary(ref x) => write!(fmt, "{}", x),
110 Bson::DateTime(date_time) => write!(fmt, "DateTime(\"{}\")", date_time),
111 Bson::Decimal128(ref d) => write!(fmt, "{}", d),
112 }
113 }
114}
115
116impl Debug for Bson {
117 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
118 match *self {
119 Bson::Double(f) => fmt.debug_tuple("Double").field(&f).finish(),
120 Bson::String(ref s) => fmt.debug_tuple("String").field(s).finish(),
121 Bson::Array(ref vec) => {
122 write!(fmt, "Array(")?;
123 Debug::fmt(vec, fmt)?;
124 write!(fmt, ")")
125 }
126 Bson::Document(ref doc) => Debug::fmt(doc, fmt),
127 Bson::Boolean(b) => fmt.debug_tuple("Boolean").field(&b).finish(),
128 Bson::Null => write!(fmt, "Null"),
129 Bson::Int32(i) => fmt.debug_tuple("Int32").field(&i).finish(),
130 Bson::Int64(i) => fmt.debug_tuple("Int64").field(&i).finish(),
131 Bson::UInt32(i) => fmt.debug_tuple("UInt32").field(&i).finish(),
132 Bson::UInt64(i) => fmt.debug_tuple("UInt64").field(&i).finish(),
133 Bson::Timestamp(ref t) => Debug::fmt(t, fmt),
134 Bson::Binary(ref b) => Debug::fmt(b, fmt),
135 Bson::DateTime(ref date_time) => Debug::fmt(date_time, fmt),
136 Bson::Decimal128(ref d) => Debug::fmt(d, fmt),
137 }
138 }
139}
140
141impl From<f32> for Bson {
142 fn from(a: f32) -> Bson {
143 Bson::Double(a.into())
144 }
145}
146
147impl From<f64> for Bson {
148 fn from(a: f64) -> Bson {
149 Bson::Double(a)
150 }
151}
152
153impl From<&str> for Bson {
154 fn from(s: &str) -> Bson {
155 Bson::String(s.to_owned())
156 }
157}
158
159impl From<String> for Bson {
160 fn from(a: String) -> Bson {
161 Bson::String(a)
162 }
163}
164
165impl From<Document> for Bson {
166 fn from(a: Document) -> Bson {
167 Bson::Document(a)
168 }
169}
170
171impl From<bool> for Bson {
172 fn from(a: bool) -> Bson {
173 Bson::Boolean(a)
174 }
175}
176
177impl From<Binary> for Bson {
178 fn from(binary: Binary) -> Bson {
179 Bson::Binary(binary)
180 }
181}
182
183impl From<Timestamp> for Bson {
184 fn from(ts: Timestamp) -> Bson {
185 Bson::Timestamp(ts)
186 }
187}
188
189impl<T> From<&T> for Bson
190where
191 T: Clone + Into<Bson>,
192{
193 fn from(t: &T) -> Bson {
194 t.clone().into()
195 }
196}
197
198impl<T> From<Vec<T>> for Bson
199where
200 T: Into<Bson>,
201{
202 fn from(v: Vec<T>) -> Bson {
203 Bson::Array(v.into_iter().map(|val| val.into()).collect())
204 }
205}
206
207impl<T> From<&[T]> for Bson
208where
209 T: Clone + Into<Bson>,
210{
211 fn from(s: &[T]) -> Bson {
212 Bson::Array(s.iter().cloned().map(|val| val.into()).collect())
213 }
214}
215
216impl<T: Into<Bson>> ::std::iter::FromIterator<T> for Bson {
217 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
228 Bson::Array(iter.into_iter().map(Into::into).collect())
229 }
230}
231
232impl From<i32> for Bson {
233 fn from(a: i32) -> Bson {
234 Bson::Int32(a)
235 }
236}
237
238impl From<i64> for Bson {
239 fn from(a: i64) -> Bson {
240 Bson::Int64(a)
241 }
242}
243
244impl From<u32> for Bson {
245 fn from(a: u32) -> Bson {
246 Bson::UInt32(a)
247 }
248}
249
250impl From<u64> for Bson {
251 fn from(a: u64) -> Bson {
252 Bson::UInt64(a)
253 }
254}
255
256
257#[cfg(feature = "chrono-0_4")]
258#[cfg_attr(docsrs, doc(cfg(feature = "chrono-0_4")))]
259impl<T: chrono::TimeZone> From<chrono::DateTime<T>> for Bson {
260 fn from(a: chrono::DateTime<T>) -> Bson {
261 Bson::DateTime(crate::DateTime::from(a))
262 }
263}
264
265#[cfg(feature = "uuid-0_8")]
266#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
267impl From<uuid::Uuid> for Bson {
268 fn from(uuid: uuid::Uuid) -> Self {
269 Bson::Binary(uuid.into())
270 }
271}
272
273impl From<crate::DateTime> for Bson {
274 fn from(dt: crate::DateTime) -> Self {
275 Bson::DateTime(dt)
276 }
277}
278
279impl<T> From<Option<T>> for Bson
280where
281 T: Into<Bson>,
282{
283 fn from(a: Option<T>) -> Bson {
284 match a {
285 None => Bson::Null,
286 Some(t) => t.into(),
287 }
288 }
289}
290
291impl From<Bson> for Value {
293 fn from(bson: Bson) -> Self {
294 bson.into_relaxed_extjson()
295 }
296}
297
298impl Bson {
299 pub fn into_relaxed_extjson(self) -> Value {
303 match self {
304 Bson::Double(v) if v.is_nan() => {
305 let s = if v.is_sign_negative() { "-NaN" } else { "NaN" };
306
307 json!({ "$numberDouble": s })
308 }
309 Bson::Double(v) if v.is_infinite() => {
310 let s = if v.is_sign_negative() {
311 "-Infinity"
312 } else {
313 "Infinity"
314 };
315
316 json!({ "$numberDouble": s })
317 }
318 Bson::Double(v) => json!(v),
319 Bson::String(v) => json!(v),
320 Bson::Array(v) => json!(v),
321 Bson::Document(v) => {
322 Value::Object(v.into_iter().map(|(k, v)| (k, Value::from(v))).collect())
323 }
324 Bson::Boolean(v) => json!(v),
325 Bson::Null => Value::Null,
326 Bson::Int32(v) => v.into(),
327 Bson::Int64(v) => v.into(),
328 Bson::UInt32(v) => v.into(),
329 Bson::UInt64(v) => v.into(),
330 Bson::Timestamp(Timestamp { time, increment }) => json!({
331 "$timestamp": {
332 "t": time,
333 "i": increment,
334 }
335 }),
336 Bson::Binary(Binary { subtype, ref bytes }) => {
337 let tval: u8 = From::from(subtype);
338 json!({
339 "$binary": {
340 "base64": base64::encode(bytes),
341 "subType": hex::encode([tval]),
342 }
343 })
344 }
345 Bson::DateTime(v) if v.timestamp_millis() >= 0 && v.to_chrono().year() <= 99999 => {
346 json!({
347 "$date": v.to_rfc3339_string(),
348 })
349 }
350 Bson::DateTime(v) => json!({
351 "$date": { "$numberLong": v.timestamp_millis().to_string() },
352 }),
353 Bson::Decimal128(_) => panic!("Decimal128 extended JSON not implemented yet."),
354 }
355 }
356
357 pub fn into_canonical_extjson(self) -> Value {
362 match self {
363 Bson::Int32(i) => json!({ "$numberInt": i.to_string() }),
364 Bson::Int64(i) => json!({ "$numberLong": i.to_string() }),
365 Bson::UInt32(i) => json!({ "$numberUInt32": i.to_string() }),
366 Bson::UInt64(i) => json!({ "$numberUInt64": i.to_string() }),
367 Bson::Double(f) if f.is_normal() => {
368 let mut s = f.to_string();
369 if f.fract() == 0.0 {
370 s.push_str(".0");
371 }
372
373 json!({ "$numberDouble": s })
374 }
375 Bson::Double(f) if f == 0.0 => {
376 let s = if f.is_sign_negative() { "-0.0" } else { "0.0" };
377
378 json!({ "$numberDouble": s })
379 }
380 Bson::DateTime(date) => {
381 json!({ "$date": { "$numberLong": date.timestamp_millis().to_string() } })
382 }
383 Bson::Array(arr) => {
384 Value::Array(arr.into_iter().map(Bson::into_canonical_extjson).collect())
385 }
386 Bson::Document(arr) => Value::Object(
387 arr.into_iter()
388 .map(|(k, v)| (k, v.into_canonical_extjson()))
389 .collect(),
390 ),
391 other => other.into_relaxed_extjson(),
392 }
393 }
394
395 pub fn element_type(&self) -> ElementType {
397 match *self {
398 Bson::Double(..) => ElementType::Double,
399 Bson::String(..) => ElementType::String,
400 Bson::Array(..) => ElementType::Array,
401 Bson::Document(..) => ElementType::EmbeddedDocument,
402 Bson::Boolean(..) => ElementType::Boolean,
403 Bson::Null => ElementType::Null,
404 Bson::Int32(..) => ElementType::Int32,
405 Bson::Int64(..) => ElementType::Int64,
406 Bson::UInt32(..) => ElementType::UInt32,
407 Bson::UInt64(..) => ElementType::UInt64,
408 Bson::Timestamp(..) => ElementType::Timestamp,
409 Bson::Binary(..) => ElementType::Binary,
410 Bson::DateTime(..) => ElementType::DateTime,
411 Bson::Decimal128(..) => ElementType::Decimal128,
412 }
413 }
414
415 pub(crate) fn into_extended_document(self) -> Document {
420 match self {
421 Bson::Timestamp(Timestamp { time, increment }) => {
422 doc! {
423 "$timestamp": {
424 "t": time,
425 "i": increment,
426 }
427 }
428 }
429 Bson::Binary(Binary { subtype, ref bytes }) => {
430 let tval: u8 = From::from(subtype);
431 doc! {
432 "$binary": {
433 "base64": base64::encode(bytes),
434 "subType": hex::encode([tval]),
435 }
436 }
437 }
438 Bson::DateTime(v) if v.timestamp_millis() >= 0 && v.to_chrono().year() <= 9999 => {
439 doc! {
440 "$date": v.to_rfc3339_string(),
441 }
442 }
443 Bson::DateTime(v) => doc! {
444 "$date": { "$numberLong": v.timestamp_millis().to_string() },
445 },
446 _ => panic!("Attempted conversion of invalid data type: {}", self),
447 }
448 }
449
450 pub(crate) fn from_extended_document(doc: Document) -> Bson {
451 if doc.len() > 2 {
452 return Bson::Document(doc);
453 }
454
455 let mut keys: Vec<_> = doc.keys().map(|s| s.as_str()).collect();
456 keys.sort_unstable();
457
458 match keys.as_slice() {
459 ["$numberInt"] => {
460 if let Ok(i) = doc.get_str("$numberInt") {
461 if let Ok(i) = i.parse() {
462 return Bson::Int32(i);
463 }
464 }
465 }
466
467 ["$numberLong"] => {
468 if let Ok(i) = doc.get_str("$numberLong") {
469 if let Ok(i) = i.parse() {
470 return Bson::Int64(i);
471 }
472 }
473 }
474
475 ["$numberDouble"] => match doc.get_str("$numberDouble") {
476 Ok("Infinity") => return Bson::Double(std::f64::INFINITY),
477 Ok("-Infinity") => return Bson::Double(std::f64::NEG_INFINITY),
478 Ok("NaN") => return Bson::Double(std::f64::NAN),
479 Ok(other) => {
480 if let Ok(d) = other.parse() {
481 return Bson::Double(d);
482 }
483 }
484 _ => {}
485 },
486
487 ["$numberDecimalBytes"] => {
488 if let Ok(bytes) = doc.get_binary_generic("$numberDecimalBytes") {
489 if let Ok(b) = bytes.clone().try_into() {
490 return Bson::Decimal128(Decimal128 { bytes: b });
491 }
492 }
493 }
494
495 ["$binary"] => {
496 if let Some(binary) = Binary::from_extended_doc(&doc) {
497 return Bson::Binary(binary);
498 }
499 }
500
501 ["$timestamp"] => {
502 if let Ok(timestamp) = doc.get_document("$timestamp") {
503 if let Ok(t) = timestamp.get_i32("t") {
504 if let Ok(i) = timestamp.get_i32("i") {
505 return Bson::Timestamp(Timestamp {
506 time: t as u32,
507 increment: i as u32,
508 });
509 }
510 }
511
512 if let Ok(t) = timestamp.get_i64("t") {
513 if let Ok(i) = timestamp.get_i64("i") {
514 if t >= 0
515 && i >= 0
516 && t <= (std::u32::MAX as i64)
517 && i <= (std::u32::MAX as i64)
518 {
519 return Bson::Timestamp(Timestamp {
520 time: t as u32,
521 increment: i as u32,
522 });
523 }
524 }
525 }
526 }
527 }
528
529 ["$date"] => {
530 if let Ok(date) = doc.get_i64("$date") {
531 return Bson::DateTime(crate::DateTime::from_millis(date));
532 }
533
534 if let Ok(date) = doc.get_str("$date") {
535 if let Ok(date) = chrono::DateTime::parse_from_rfc3339(date) {
536 return Bson::DateTime(crate::DateTime::from_chrono(date));
537 }
538 }
539 }
540
541 _ => {}
542 };
543
544 Bson::Document(
545 doc.into_iter()
546 .map(|(k, v)| {
547 let v = match v {
548 Bson::Document(v) => Bson::from_extended_document(v),
549 other => other,
550 };
551
552 (k, v)
553 })
554 .collect(),
555 )
556 }
557}
558
559impl Bson {
561 pub fn as_f64(&self) -> Option<f64> {
563 match *self {
564 Bson::Double(v) => Some(v),
565 _ => None,
566 }
567 }
568
569 pub fn as_str(&self) -> Option<&str> {
571 match *self {
572 Bson::String(ref s) => Some(s),
573 _ => None,
574 }
575 }
576
577 pub fn as_str_mut(&mut self) -> Option<&mut str> {
580 match *self {
581 Bson::String(ref mut s) => Some(s),
582 _ => None,
583 }
584 }
585
586 pub fn as_array(&self) -> Option<&Array> {
588 match *self {
589 Bson::Array(ref v) => Some(v),
590 _ => None,
591 }
592 }
593
594 pub fn as_array_mut(&mut self) -> Option<&mut Array> {
596 match *self {
597 Bson::Array(ref mut v) => Some(v),
598 _ => None,
599 }
600 }
601
602 pub fn as_document(&self) -> Option<&Document> {
604 match *self {
605 Bson::Document(ref v) => Some(v),
606 _ => None,
607 }
608 }
609
610 pub fn as_document_mut(&mut self) -> Option<&mut Document> {
612 match *self {
613 Bson::Document(ref mut v) => Some(v),
614 _ => None,
615 }
616 }
617
618 pub fn as_bool(&self) -> Option<bool> {
620 match *self {
621 Bson::Boolean(v) => Some(v),
622 _ => None,
623 }
624 }
625
626 pub fn as_i32(&self) -> Option<i32> {
628 match *self {
629 Bson::Int32(v) => Some(v),
630 _ => None,
631 }
632 }
633
634 pub fn as_i64(&self) -> Option<i64> {
636 match *self {
637 Bson::Int64(v) => Some(v),
638 _ => None,
639 }
640 }
641
642 pub fn as_u32(&self) -> Option<u32> {
644 match *self {
645 Bson::UInt32(v) => Some(v),
646 _ => None,
647 }
648 }
649
650 pub fn as_u64(&self) -> Option<u64> {
652 match *self {
653 Bson::UInt64(v) => Some(v),
654 _ => None,
655 }
656 }
657
658 pub fn as_datetime(&self) -> Option<&crate::DateTime> {
660 match *self {
661 Bson::DateTime(ref v) => Some(v),
662 _ => None,
663 }
664 }
665
666 pub fn as_datetime_mut(&mut self) -> Option<&mut crate::DateTime> {
669 match *self {
670 Bson::DateTime(ref mut v) => Some(v),
671 _ => None,
672 }
673 }
674
675 pub fn as_timestamp(&self) -> Option<Timestamp> {
677 match *self {
678 Bson::Timestamp(timestamp) => Some(timestamp),
679 _ => None,
680 }
681 }
682
683 pub fn as_null(&self) -> Option<()> {
685 match *self {
686 Bson::Null => Some(()),
687 _ => None,
688 }
689 }
690
691}
692
693#[derive(Debug, Eq, Ord, PartialEq, PartialOrd, Clone, Copy, Hash)]
695pub struct Timestamp {
696 pub time: u32,
698
699 pub increment: u32,
702}
703
704impl Display for Timestamp {
705 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
706 write!(fmt, "Timestamp({}, {})", self.time, self.increment)
707 }
708}
709
710impl Timestamp {
711 pub(crate) fn to_le_i64(self) -> i64 {
712 let upper = (self.time.to_le() as u64) << 32;
713 let lower = self.increment.to_le() as u64;
714
715 (upper | lower) as i64
716 }
717
718 pub(crate) fn from_le_i64(val: i64) -> Self {
719 let ts = val.to_le();
720
721 Timestamp {
722 time: ((ts as u64) >> 32) as u32,
723 increment: (ts & 0xFFFF_FFFF) as u32,
724 }
725 }
726}
727
728
729#[derive(Debug, Clone, PartialEq)]
731pub struct Binary {
732 pub subtype: BinarySubtype,
734
735 pub bytes: Vec<u8>,
737}
738
739impl Display for Binary {
740 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
741 write!(
742 fmt,
743 "Binary({:#x}, {})",
744 u8::from(self.subtype),
745 base64::encode(&self.bytes)
746 )
747 }
748}
749
750impl Binary {
751 pub(crate) fn from_extended_doc(doc: &Document) -> Option<Self> {
752 let binary_doc = doc.get_document("$binary").ok()?;
753
754 if let Ok(bytes) = binary_doc.get_str("base64") {
755 let bytes = base64::decode(bytes).ok()?;
756 let subtype = binary_doc.get_str("subType").ok()?;
757 let subtype = hex::decode(subtype).ok()?;
758 if subtype.len() == 1 {
759 Some(Self {
760 bytes,
761 subtype: subtype[0].into(),
762 })
763 } else {
764 None
765 }
766 } else {
767 let binary = binary_doc.get_binary_generic("bytes").ok()?;
770 let subtype = binary_doc.get_i32("subType").ok()?;
771
772 Some(Self {
773 bytes: binary.clone(),
774 subtype: u8::try_from(subtype).ok()?.into(),
775 })
776 }
777 }
778}