1use std::{
25 collections::HashSet,
26 convert::TryFrom,
27 fmt::{self, Debug, Display, Formatter},
28 hash::Hash,
29 ops::Index,
30};
31
32pub use crate::document::Document;
33use crate::{
34 oid,
35 raw::{doc_writer::DocWriter, CString},
36 spec::ElementType,
37 Binary,
38 Decimal128,
39 RawBsonRef,
40};
41
42#[derive(Clone, Default, PartialEq)]
44pub enum Bson {
45 Double(f64),
47 String(String),
49 Array(Array),
51 Document(Document),
53 Boolean(bool),
55 #[default]
57 Null,
58 RegularExpression(Regex),
60 JavaScriptCode(String),
62 JavaScriptCodeWithScope(JavaScriptCodeWithScope),
64 Int32(i32),
66 Int64(i64),
68 Timestamp(Timestamp),
70 Binary(Binary),
72 ObjectId(oid::ObjectId),
74 DateTime(crate::DateTime),
76 Symbol(String),
78 Decimal128(Decimal128),
80 Undefined,
82 MaxKey,
84 MinKey,
86 DbPointer(DbPointer),
88}
89
90pub type Array = Vec<Bson>;
92
93impl Hash for Bson {
94 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
95 match self {
96 Bson::Double(double) => {
97 if *double == 0.0_f64 {
98 0.0_f64.to_bits().hash(state);
102 } else {
103 double.to_bits().hash(state);
104 }
105 }
106 Bson::String(x) => x.hash(state),
107 Bson::Array(x) => x.hash(state),
108 Bson::Document(x) => x.hash(state),
109 Bson::Boolean(x) => x.hash(state),
110 Bson::RegularExpression(x) => x.hash(state),
111 Bson::JavaScriptCode(x) => x.hash(state),
112 Bson::JavaScriptCodeWithScope(x) => x.hash(state),
113 Bson::Int32(x) => x.hash(state),
114 Bson::Int64(x) => x.hash(state),
115 Bson::Timestamp(x) => x.hash(state),
116 Bson::Binary(x) => x.hash(state),
117 Bson::ObjectId(x) => x.hash(state),
118 Bson::DateTime(x) => x.hash(state),
119 Bson::Symbol(x) => x.hash(state),
120 Bson::Decimal128(x) => x.hash(state),
121 Bson::DbPointer(x) => x.hash(state),
122 Bson::Null | Bson::Undefined | Bson::MaxKey | Bson::MinKey => (),
123 }
124 }
125}
126
127impl Eq for Bson {}
128
129impl Display for Bson {
130 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
131 match *self {
132 Bson::Double(f) => write!(fmt, "{}", f),
133 Bson::String(ref s) => write!(fmt, "\"{}\"", s),
134 Bson::Array(ref vec) => {
135 fmt.write_str("[")?;
136
137 let indent = fmt.width().unwrap_or(2);
138 let indent_str = " ".repeat(indent);
139
140 let mut first = true;
141 for bson in vec {
142 if !first {
143 fmt.write_str(", ")?;
144 }
145 if fmt.alternate() {
146 write!(fmt, "\n{indent_str}")?;
147 match bson {
148 Bson::Array(_arr) => {
149 let new_indent = indent + 2;
150 write!(fmt, "{bson:#new_indent$}")?;
151 }
152 Bson::Document(ref doc) => {
153 let new_indent = indent + 2;
154 write!(fmt, "{doc:#new_indent$}")?;
155 }
156 _ => {
157 write!(fmt, "{}", bson)?;
158 }
159 }
160 } else {
161 write!(fmt, "{}", bson)?;
162 }
163 first = false;
164 }
165 if fmt.alternate() && !vec.is_empty() {
166 let closing_bracket_indent_str = " ".repeat(indent - 2);
167 write!(fmt, "\n{closing_bracket_indent_str}]")
168 } else {
169 fmt.write_str("]")
170 }
171 }
172 Bson::Document(ref doc) => {
173 if fmt.alternate() {
174 write!(fmt, "{doc:#}")
175 } else {
176 write!(fmt, "{doc}")
177 }
178 }
179 Bson::Boolean(b) => write!(fmt, "{}", b),
180 Bson::Null => write!(fmt, "null"),
181 Bson::RegularExpression(ref x) => write!(fmt, "{}", x),
182 Bson::JavaScriptCode(ref code)
183 | Bson::JavaScriptCodeWithScope(JavaScriptCodeWithScope { ref code, .. }) => {
184 fmt.write_str(code)
185 }
186 Bson::Int32(i) => write!(fmt, "{}", i),
187 Bson::Int64(i) => write!(fmt, "{}", i),
188 Bson::Timestamp(ref x) => write!(fmt, "{}", x),
189 Bson::Binary(ref x) => write!(fmt, "{}", x),
190 Bson::ObjectId(ref id) => write!(fmt, "ObjectId(\"{}\")", id),
191 Bson::DateTime(date_time) => write!(fmt, "DateTime(\"{}\")", date_time),
192 Bson::Symbol(ref sym) => write!(fmt, "Symbol(\"{}\")", sym),
193 Bson::Decimal128(ref d) => write!(fmt, "{}", d),
194 Bson::Undefined => write!(fmt, "undefined"),
195 Bson::MinKey => write!(fmt, "MinKey"),
196 Bson::MaxKey => write!(fmt, "MaxKey"),
197 Bson::DbPointer(DbPointer {
198 ref namespace,
199 ref id,
200 }) => write!(fmt, "DbPointer({}, {})", namespace, id),
201 }
202 }
203}
204
205impl Debug for Bson {
206 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
207 match *self {
208 Bson::Double(f) => fmt.debug_tuple("Double").field(&f).finish(),
209 Bson::String(ref s) => fmt.debug_tuple("String").field(s).finish(),
210 Bson::Array(ref vec) => {
211 write!(fmt, "Array(")?;
212 Debug::fmt(vec, fmt)?;
213 write!(fmt, ")")
214 }
215 Bson::Document(ref doc) => Debug::fmt(doc, fmt),
216 Bson::Boolean(b) => fmt.debug_tuple("Boolean").field(&b).finish(),
217 Bson::Null => write!(fmt, "Null"),
218 Bson::RegularExpression(ref regex) => Debug::fmt(regex, fmt),
219 Bson::JavaScriptCode(ref code) => {
220 fmt.debug_tuple("JavaScriptCode").field(code).finish()
221 }
222 Bson::JavaScriptCodeWithScope(ref code) => Debug::fmt(code, fmt),
223 Bson::Int32(i) => fmt.debug_tuple("Int32").field(&i).finish(),
224 Bson::Int64(i) => fmt.debug_tuple("Int64").field(&i).finish(),
225 Bson::Timestamp(ref t) => Debug::fmt(t, fmt),
226 Bson::Binary(ref b) => Debug::fmt(b, fmt),
227 Bson::ObjectId(ref id) => Debug::fmt(id, fmt),
228 Bson::DateTime(ref date_time) => Debug::fmt(date_time, fmt),
229 Bson::Symbol(ref sym) => fmt.debug_tuple("Symbol").field(sym).finish(),
230 Bson::Decimal128(ref d) => Debug::fmt(d, fmt),
231 Bson::Undefined => write!(fmt, "Undefined"),
232 Bson::MinKey => write!(fmt, "MinKey"),
233 Bson::MaxKey => write!(fmt, "MaxKey"),
234 Bson::DbPointer(ref pointer) => Debug::fmt(pointer, fmt),
235 }
236 }
237}
238
239impl Index<&str> for Bson {
240 type Output = Bson;
241
242 fn index(&self, index: &str) -> &Self::Output {
243 match *self {
244 Bson::Document(ref doc) => match doc.get(index) {
245 Some(v) => v,
246 None => &Bson::Null,
247 },
248 _ => &Bson::Null,
249 }
250 }
251}
252
253impl From<f32> for Bson {
254 fn from(a: f32) -> Bson {
255 Bson::Double(a.into())
256 }
257}
258
259impl From<f64> for Bson {
260 fn from(a: f64) -> Bson {
261 Bson::Double(a)
262 }
263}
264
265impl From<&str> for Bson {
266 fn from(s: &str) -> Bson {
267 Bson::String(s.to_owned())
268 }
269}
270
271impl From<String> for Bson {
272 fn from(a: String) -> Bson {
273 Bson::String(a)
274 }
275}
276
277impl From<crate::raw::CString> for Bson {
278 fn from(a: crate::raw::CString) -> Bson {
279 Bson::String(a.into_string())
280 }
281}
282
283impl From<Document> for Bson {
284 fn from(a: Document) -> Bson {
285 Bson::Document(a)
286 }
287}
288
289impl From<bool> for Bson {
290 fn from(a: bool) -> Bson {
291 Bson::Boolean(a)
292 }
293}
294
295impl From<Regex> for Bson {
296 fn from(regex: Regex) -> Bson {
297 Bson::RegularExpression(regex)
298 }
299}
300
301impl From<JavaScriptCodeWithScope> for Bson {
302 fn from(code_with_scope: JavaScriptCodeWithScope) -> Bson {
303 Bson::JavaScriptCodeWithScope(code_with_scope)
304 }
305}
306
307impl From<Binary> for Bson {
308 fn from(binary: Binary) -> Bson {
309 Bson::Binary(binary)
310 }
311}
312
313impl From<Timestamp> for Bson {
314 fn from(ts: Timestamp) -> Bson {
315 Bson::Timestamp(ts)
316 }
317}
318
319impl<T> From<&T> for Bson
320where
321 T: Clone + Into<Bson>,
322{
323 fn from(t: &T) -> Bson {
324 t.clone().into()
325 }
326}
327
328impl<T> From<&mut T> for Bson
329where
330 for<'a> &'a T: Into<Bson>,
331{
332 fn from(t: &mut T) -> Bson {
333 (&*t).into()
334 }
335}
336
337impl<T> From<Vec<T>> for Bson
338where
339 T: Into<Bson>,
340{
341 fn from(v: Vec<T>) -> Bson {
342 Bson::Array(v.into_iter().map(|val| val.into()).collect())
343 }
344}
345
346impl<T: Into<Bson>, S> From<HashSet<T, S>> for Bson {
347 fn from(s: HashSet<T, S>) -> Bson {
348 Bson::from_iter(s)
349 }
350}
351
352impl<T, const N: usize> From<[T; N]> for Bson
353where
354 T: Into<Bson>,
355{
356 fn from(value: [T; N]) -> Self {
357 Bson::Array(value.into_iter().map(|v| v.into()).collect())
358 }
359}
360
361impl<T> From<&[T]> for Bson
362where
363 T: Clone + Into<Bson>,
364{
365 fn from(s: &[T]) -> Bson {
366 Bson::Array(s.iter().cloned().map(|val| val.into()).collect())
367 }
368}
369
370impl<T: Into<Bson>> ::std::iter::FromIterator<T> for Bson {
371 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
382 Bson::Array(iter.into_iter().map(Into::into).collect())
383 }
384}
385
386impl From<i32> for Bson {
387 fn from(a: i32) -> Bson {
388 Bson::Int32(a)
389 }
390}
391
392impl From<i64> for Bson {
393 fn from(a: i64) -> Bson {
394 Bson::Int64(a)
395 }
396}
397
398impl From<u32> for Bson {
399 fn from(a: u32) -> Bson {
400 if let Ok(i) = i32::try_from(a) {
401 Bson::Int32(i)
402 } else {
403 Bson::Int64(a.into())
404 }
405 }
406}
407
408impl From<[u8; 12]> for Bson {
409 fn from(a: [u8; 12]) -> Bson {
410 Bson::ObjectId(oid::ObjectId::from_bytes(a))
411 }
412}
413
414impl From<oid::ObjectId> for Bson {
415 fn from(a: oid::ObjectId) -> Bson {
416 Bson::ObjectId(a)
417 }
418}
419
420#[cfg(feature = "time-0_3")]
421impl From<time::OffsetDateTime> for Bson {
422 fn from(a: time::OffsetDateTime) -> Bson {
423 Bson::DateTime(crate::DateTime::from(a))
424 }
425}
426
427#[cfg(feature = "chrono-0_4")]
428impl<T: chrono::TimeZone> From<chrono::DateTime<T>> for Bson {
429 fn from(a: chrono::DateTime<T>) -> Bson {
430 Bson::DateTime(crate::DateTime::from(a))
431 }
432}
433
434#[cfg(feature = "jiff-0_2")]
435impl From<jiff::Timestamp> for Bson {
436 fn from(a: jiff::Timestamp) -> Bson {
437 Bson::DateTime(crate::DateTime::from(a))
438 }
439}
440
441#[cfg(feature = "uuid-1")]
442impl From<uuid::Uuid> for Bson {
443 fn from(uuid: uuid::Uuid) -> Self {
444 Bson::Binary(uuid.into())
445 }
446}
447
448impl From<crate::DateTime> for Bson {
449 fn from(dt: crate::DateTime) -> Self {
450 Bson::DateTime(dt)
451 }
452}
453
454impl From<DbPointer> for Bson {
455 fn from(a: DbPointer) -> Bson {
456 Bson::DbPointer(a)
457 }
458}
459
460impl From<Decimal128> for Bson {
461 fn from(d: Decimal128) -> Self {
462 Bson::Decimal128(d)
463 }
464}
465
466impl<T> From<Option<T>> for Bson
467where
468 T: Into<Bson>,
469{
470 fn from(a: Option<T>) -> Bson {
471 match a {
472 None => Bson::Null,
473 Some(t) => t.into(),
474 }
475 }
476}
477
478impl Bson {
479 pub fn element_type(&self) -> ElementType {
481 match *self {
482 Bson::Double(..) => ElementType::Double,
483 Bson::String(..) => ElementType::String,
484 Bson::Array(..) => ElementType::Array,
485 Bson::Document(..) => ElementType::EmbeddedDocument,
486 Bson::Boolean(..) => ElementType::Boolean,
487 Bson::Null => ElementType::Null,
488 Bson::RegularExpression(..) => ElementType::RegularExpression,
489 Bson::JavaScriptCode(..) => ElementType::JavaScriptCode,
490 Bson::JavaScriptCodeWithScope(..) => ElementType::JavaScriptCodeWithScope,
491 Bson::Int32(..) => ElementType::Int32,
492 Bson::Int64(..) => ElementType::Int64,
493 Bson::Timestamp(..) => ElementType::Timestamp,
494 Bson::Binary(..) => ElementType::Binary,
495 Bson::ObjectId(..) => ElementType::ObjectId,
496 Bson::DateTime(..) => ElementType::DateTime,
497 Bson::Symbol(..) => ElementType::Symbol,
498 Bson::Decimal128(..) => ElementType::Decimal128,
499 Bson::Undefined => ElementType::Undefined,
500 Bson::MaxKey => ElementType::MaxKey,
501 Bson::MinKey => ElementType::MinKey,
502 Bson::DbPointer(..) => ElementType::DbPointer,
503 }
504 }
505
506 #[cfg(feature = "serde")]
511 pub(crate) fn into_extended_document(self, rawbson: bool) -> Document {
512 match self {
513 Bson::RegularExpression(Regex {
514 ref pattern,
515 ref options,
516 }) => {
517 let mut chars: Vec<_> = options.as_str().chars().collect();
518 chars.sort_unstable();
519
520 let options: String = chars.into_iter().collect();
521
522 doc! {
523 "$regularExpression": {
524 "pattern": pattern,
525 "options": options,
526 }
527 }
528 }
529 Bson::JavaScriptCode(ref code) => {
530 doc! {
531 "$code": code,
532 }
533 }
534 Bson::JavaScriptCodeWithScope(JavaScriptCodeWithScope { code, scope }) => {
535 doc! {
536 "$code": code,
537 "$scope": scope,
538 }
539 }
540 Bson::Timestamp(Timestamp { time, increment }) => {
541 doc! {
542 "$timestamp": {
543 "t": time,
544 "i": increment,
545 }
546 }
547 }
548 Bson::Binary(Binary { subtype, bytes }) => {
549 let tval: u8 = From::from(subtype);
550 if rawbson {
551 doc! {
552 "$binary": {
553 "bytes": Binary { subtype: crate::spec::BinarySubtype::Generic, bytes },
554 "subType": Bson::Int32(tval.into())
555 }
556 }
557 } else {
558 doc! {
559 "$binary": {
560 "base64": crate::base64::encode(bytes),
561 "subType": hex::encode([tval]),
562 }
563 }
564 }
565 }
566 Bson::ObjectId(ref v) => {
567 doc! {
568 "$oid": v.to_string(),
569 }
570 }
571 Bson::DateTime(v) if rawbson => doc! {
572 "$date": v.timestamp_millis(),
573 },
574 Bson::DateTime(v) if v.timestamp_millis() >= 0 && v.to_time_0_3().year() <= 9999 => {
575 doc! {
576 "$date": v.try_to_rfc3339_string().unwrap(),
578 }
579 }
580 Bson::DateTime(v) => doc! {
581 "$date": { "$numberLong": v.timestamp_millis().to_string() },
582 },
583 Bson::Symbol(ref v) => {
584 doc! {
585 "$symbol": v.to_owned(),
586 }
587 }
588 Bson::Undefined => {
589 doc! {
590 "$undefined": true,
591 }
592 }
593 Bson::MinKey => {
594 doc! {
595 "$minKey": 1,
596 }
597 }
598 Bson::MaxKey => {
599 doc! {
600 "$maxKey": 1,
601 }
602 }
603 Bson::DbPointer(DbPointer {
604 ref namespace,
605 ref id,
606 }) => {
607 doc! {
608 "$dbPointer": {
609 "$ref": namespace,
610 "$id": {
611 "$oid": id.to_string()
612 }
613 }
614 }
615 }
616 _ => panic!("Attempted conversion of invalid data type: {}", self),
617 }
618 }
619
620 #[cfg(feature = "serde")]
621 pub(crate) fn from_extended_document(doc: Document) -> Bson {
622 if doc.len() > 2 {
623 return Bson::Document(doc);
624 }
625
626 let mut keys: Vec<_> = doc.keys().map(|s| s.as_str()).collect();
627 keys.sort_unstable();
628
629 match keys.as_slice() {
630 ["$oid"] => {
631 if let Ok(oid) = doc.get_str("$oid") {
632 if let Ok(oid) = crate::oid::ObjectId::parse_str(oid) {
633 return Bson::ObjectId(oid);
634 }
635 }
636 }
637
638 ["$symbol"] => {
639 if let Ok(symbol) = doc.get_str("$symbol") {
640 return Bson::Symbol(symbol.into());
641 }
642 }
643
644 ["$numberInt"] => {
645 if let Ok(i) = doc.get_str("$numberInt") {
646 if let Ok(i) = i.parse() {
647 return Bson::Int32(i);
648 }
649 }
650 }
651
652 ["$numberLong"] => {
653 if let Ok(i) = doc.get_str("$numberLong") {
654 if let Ok(i) = i.parse() {
655 return Bson::Int64(i);
656 }
657 }
658 }
659
660 ["$numberDouble"] => match doc.get_str("$numberDouble") {
661 Ok("Infinity") => return Bson::Double(f64::INFINITY),
662 Ok("-Infinity") => return Bson::Double(f64::NEG_INFINITY),
663 Ok("NaN") => return Bson::Double(f64::NAN),
664 Ok(other) => {
665 if let Ok(d) = other.parse() {
666 return Bson::Double(d);
667 }
668 }
669 _ => {}
670 },
671
672 ["$numberDecimal"] => {
673 if let Ok(d) = doc.get_str("$numberDecimal") {
674 if let Ok(d) = d.parse() {
675 return Bson::Decimal128(d);
676 }
677 }
678 }
679
680 ["$numberDecimalBytes"] => {
681 if let Ok(bytes) = doc.get_binary_generic("$numberDecimalBytes") {
682 if let Ok(b) = bytes.clone().try_into() {
683 return Bson::Decimal128(Decimal128 { bytes: b });
684 }
685 }
686 }
687
688 ["$binary"] => {
689 if let Some(binary) = Binary::from_extended_doc(&doc) {
690 return Bson::Binary(binary);
691 }
692 }
693
694 ["$code"] => {
695 if let Ok(code) = doc.get_str("$code") {
696 return Bson::JavaScriptCode(code.into());
697 }
698 }
699
700 ["$code", "$scope"] => {
701 if let Ok(code) = doc.get_str("$code") {
702 if let Ok(scope) = doc.get_document("$scope") {
703 return Bson::JavaScriptCodeWithScope(JavaScriptCodeWithScope {
704 code: code.into(),
705 scope: scope.clone(),
706 });
707 }
708 }
709 }
710
711 ["$timestamp"] => {
712 if let Ok(timestamp) = doc.get_document("$timestamp") {
713 if let Ok(t) = timestamp.get_i32("t") {
714 if let Ok(i) = timestamp.get_i32("i") {
715 return Bson::Timestamp(Timestamp {
716 time: t as u32,
717 increment: i as u32,
718 });
719 }
720 }
721
722 if let Ok(t) = timestamp.get_i64("t") {
723 if let Ok(i) = timestamp.get_i64("i") {
724 if t >= 0 && i >= 0 && t <= (u32::MAX as i64) && i <= (u32::MAX as i64)
725 {
726 return Bson::Timestamp(Timestamp {
727 time: t as u32,
728 increment: i as u32,
729 });
730 }
731 }
732 }
733 }
734 }
735
736 ["$regularExpression"] => {
737 if let Ok(regex) = doc.get_document("$regularExpression") {
738 if let Ok(pattern) = regex.get_str("pattern") {
739 if let Ok(options) = regex.get_str("options") {
740 if let Ok(regex) = Regex::from_strings(pattern, options) {
741 return Bson::RegularExpression(regex);
742 }
743 }
744 }
745 }
746 }
747
748 ["$dbPointer"] => {
749 if let Ok(db_pointer) = doc.get_document("$dbPointer") {
750 if let Ok(ns) = db_pointer.get_str("$ref") {
751 if let Ok(id) = db_pointer.get_object_id("$id") {
752 return Bson::DbPointer(DbPointer {
753 namespace: ns.into(),
754 id,
755 });
756 }
757 }
758 }
759 }
760
761 ["$date"] => {
762 if let Ok(date) = doc.get_i64("$date") {
763 return Bson::DateTime(crate::DateTime::from_millis(date));
764 }
765
766 if let Ok(date) = doc.get_str("$date") {
767 if let Ok(dt) = crate::DateTime::parse_rfc3339_str(date) {
768 return Bson::DateTime(dt);
769 }
770 }
771 }
772
773 ["$minKey"] => {
774 let min_key = doc.get("$minKey");
775
776 if min_key == Some(&Bson::Int32(1)) || min_key == Some(&Bson::Int64(1)) {
777 return Bson::MinKey;
778 }
779 }
780
781 ["$maxKey"] => {
782 let max_key = doc.get("$maxKey");
783
784 if max_key == Some(&Bson::Int32(1)) || max_key == Some(&Bson::Int64(1)) {
785 return Bson::MaxKey;
786 }
787 }
788
789 ["$undefined"] => {
790 if doc.get("$undefined") == Some(&Bson::Boolean(true)) {
791 return Bson::Undefined;
792 }
793 }
794
795 _ => {}
796 };
797
798 Bson::Document(
799 doc.into_iter()
800 .map(|(k, v)| {
801 let v = match v {
802 Bson::Document(v) => Bson::from_extended_document(v),
803 other => other,
804 };
805
806 (k, v)
807 })
808 .collect(),
809 )
810 }
811
812 #[cfg(feature = "serde")]
815 pub(crate) fn as_unexpected(&self) -> serde::de::Unexpected<'_> {
816 use serde::de::Unexpected;
817 match self {
818 Bson::Array(_) => Unexpected::Seq,
819 Bson::Binary(b) => Unexpected::Bytes(b.bytes.as_slice()),
820 Bson::Boolean(b) => Unexpected::Bool(*b),
821 Bson::DbPointer(_) => Unexpected::Other("dbpointer"),
822 Bson::Document(_) => Unexpected::Map,
823 Bson::Double(f) => Unexpected::Float(*f),
824 Bson::Int32(i) => Unexpected::Signed(*i as i64),
825 Bson::Int64(i) => Unexpected::Signed(*i),
826 Bson::JavaScriptCode(_) => Unexpected::Other("javascript code"),
827 Bson::JavaScriptCodeWithScope(_) => Unexpected::Other("javascript code with scope"),
828 Bson::MaxKey => Unexpected::Other("maxkey"),
829 Bson::MinKey => Unexpected::Other("minkey"),
830 Bson::Null => Unexpected::Unit,
831 Bson::Undefined => Unexpected::Other("undefined"),
832 Bson::ObjectId(_) => Unexpected::Other("objectid"),
833 Bson::RegularExpression(_) => Unexpected::Other("regex"),
834 Bson::String(s) => Unexpected::Str(s.as_str()),
835 Bson::Symbol(_) => Unexpected::Other("symbol"),
836 Bson::Timestamp(_) => Unexpected::Other("timestamp"),
837 Bson::DateTime(_) => Unexpected::Other("datetime"),
838 Bson::Decimal128(_) => Unexpected::Other("decimal128"),
839 }
840 }
841
842 pub(crate) fn append_to(&self, buf: &mut Vec<u8>) -> crate::error::Result<()> {
843 match self {
844 Self::Int32(val) => RawBsonRef::Int32(*val).append_to(buf),
845 Self::Int64(val) => RawBsonRef::Int64(*val).append_to(buf),
846 Self::Double(val) => RawBsonRef::Double(*val).append_to(buf),
847 Self::Binary(bin) => RawBsonRef::Binary(crate::RawBinaryRef {
848 subtype: bin.subtype,
849 bytes: &bin.bytes,
850 })
851 .append_to(buf),
852 Self::String(s) => RawBsonRef::String(s).append_to(buf),
853 Self::Array(arr) => {
854 let mut writer = DocWriter::open(buf);
855 for (ix, v) in arr.iter().enumerate() {
856 writer.append_key(
857 v.element_type(),
858 &crate::raw::CString::from_string_unchecked(ix.to_string()),
859 );
860 v.append_to(writer.buffer())?;
861 }
862 }
863 Self::Document(doc) => doc.append_to(buf)?,
864 Self::Boolean(b) => RawBsonRef::Boolean(*b).append_to(buf),
865 Self::RegularExpression(re) => RawBsonRef::RegularExpression(crate::RawRegexRef {
866 pattern: &re.pattern,
867 options: &re.options,
868 })
869 .append_to(buf),
870 Self::JavaScriptCode(js) => RawBsonRef::JavaScriptCode(js).append_to(buf),
871 Self::JavaScriptCodeWithScope(cws) => {
872 let start = buf.len();
873 buf.extend(0i32.to_le_bytes()); RawBsonRef::String(&cws.code).append_to(buf);
875 cws.scope.append_to(buf)?;
876 let len: i32 = (buf.len() - start) as i32;
877 buf[start..start + 4].copy_from_slice(&len.to_le_bytes());
878 }
879 Self::Timestamp(ts) => RawBsonRef::Timestamp(*ts).append_to(buf),
880 Self::ObjectId(oid) => RawBsonRef::ObjectId(*oid).append_to(buf),
881 Self::DateTime(dt) => RawBsonRef::DateTime(*dt).append_to(buf),
882 Self::Symbol(s) => RawBsonRef::Symbol(s).append_to(buf),
883 Self::Decimal128(d) => RawBsonRef::Decimal128(*d).append_to(buf),
884 Self::DbPointer(dbp) => {
885 RawBsonRef::String(&dbp.namespace).append_to(buf);
886 RawBsonRef::ObjectId(dbp.id).append_to(buf);
887 }
888 Self::Null | Self::Undefined | Self::MinKey | Self::MaxKey => {}
889 }
890 Ok(())
891 }
892}
893
894impl Bson {
896 pub fn as_f64(&self) -> Option<f64> {
899 match *self {
900 Bson::Double(v) => Some(v),
901 _ => None,
902 }
903 }
904
905 pub fn as_str(&self) -> Option<&str> {
908 match *self {
909 Bson::String(ref s) => Some(s),
910 _ => None,
911 }
912 }
913
914 pub fn as_str_mut(&mut self) -> Option<&mut str> {
917 match *self {
918 Bson::String(ref mut s) => Some(s),
919 _ => None,
920 }
921 }
922
923 pub fn as_array(&self) -> Option<&Array> {
925 match *self {
926 Bson::Array(ref v) => Some(v),
927 _ => None,
928 }
929 }
930
931 pub fn as_array_mut(&mut self) -> Option<&mut Array> {
934 match *self {
935 Bson::Array(ref mut v) => Some(v),
936 _ => None,
937 }
938 }
939
940 pub fn as_document(&self) -> Option<&Document> {
942 match *self {
943 Bson::Document(ref v) => Some(v),
944 _ => None,
945 }
946 }
947
948 pub fn as_document_mut(&mut self) -> Option<&mut Document> {
951 match *self {
952 Bson::Document(ref mut v) => Some(v),
953 _ => None,
954 }
955 }
956
957 pub fn as_bool(&self) -> Option<bool> {
959 match *self {
960 Bson::Boolean(v) => Some(v),
961 _ => None,
962 }
963 }
964
965 pub fn as_i32(&self) -> Option<i32> {
967 match *self {
968 Bson::Int32(v) => Some(v),
969 _ => None,
970 }
971 }
972
973 pub fn as_i64(&self) -> Option<i64> {
975 match *self {
976 Bson::Int64(v) => Some(v),
977 _ => None,
978 }
979 }
980
981 pub fn as_object_id(&self) -> Option<oid::ObjectId> {
983 match *self {
984 Bson::ObjectId(v) => Some(v),
985 _ => None,
986 }
987 }
988
989 pub fn as_object_id_mut(&mut self) -> Option<&mut oid::ObjectId> {
992 match *self {
993 Bson::ObjectId(ref mut v) => Some(v),
994 _ => None,
995 }
996 }
997
998 pub fn as_datetime(&self) -> Option<&crate::DateTime> {
1000 match *self {
1001 Bson::DateTime(ref v) => Some(v),
1002 _ => None,
1003 }
1004 }
1005
1006 pub fn as_datetime_mut(&mut self) -> Option<&mut crate::DateTime> {
1009 match *self {
1010 Bson::DateTime(ref mut v) => Some(v),
1011 _ => None,
1012 }
1013 }
1014
1015 pub fn as_symbol(&self) -> Option<&str> {
1017 match *self {
1018 Bson::Symbol(ref v) => Some(v),
1019 _ => None,
1020 }
1021 }
1022
1023 pub fn as_symbol_mut(&mut self) -> Option<&mut str> {
1026 match *self {
1027 Bson::Symbol(ref mut v) => Some(v),
1028 _ => None,
1029 }
1030 }
1031
1032 pub fn as_timestamp(&self) -> Option<Timestamp> {
1034 match *self {
1035 Bson::Timestamp(timestamp) => Some(timestamp),
1036 _ => None,
1037 }
1038 }
1039
1040 pub fn as_null(&self) -> Option<()> {
1042 match *self {
1043 Bson::Null => Some(()),
1044 _ => None,
1045 }
1046 }
1047
1048 pub fn as_db_pointer(&self) -> Option<&DbPointer> {
1050 match self {
1051 Bson::DbPointer(ref db_pointer) => Some(db_pointer),
1052 _ => None,
1053 }
1054 }
1055}
1056
1057#[derive(Debug, Eq, Ord, PartialEq, PartialOrd, Clone, Copy, Hash)]
1059pub struct Timestamp {
1060 pub time: u32,
1062
1063 pub increment: u32,
1066}
1067
1068impl Display for Timestamp {
1069 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1070 write!(fmt, "Timestamp({}, {})", self.time, self.increment)
1071 }
1072}
1073
1074impl Timestamp {
1075 pub(crate) fn to_le_bytes(self) -> [u8; 8] {
1076 let mut out = [0; 8];
1077 out[0..4].copy_from_slice(&self.increment.to_le_bytes());
1078 out[4..8].copy_from_slice(&self.time.to_le_bytes());
1079 out
1080 }
1081
1082 pub(crate) fn from_le_bytes(bytes: [u8; 8]) -> Self {
1083 let mut inc_bytes = [0; 4];
1084 inc_bytes.copy_from_slice(&bytes[0..4]);
1085 let mut time_bytes = [0; 4];
1086 time_bytes.copy_from_slice(&bytes[4..8]);
1087 Self {
1088 increment: u32::from_le_bytes(inc_bytes),
1089 time: u32::from_le_bytes(time_bytes),
1090 }
1091 }
1092}
1093
1094#[derive(Debug, Clone, Eq, PartialEq, Hash)]
1096pub struct Regex {
1097 pub pattern: CString,
1099
1100 pub options: CString,
1108}
1109
1110impl Regex {
1111 #[cfg(any(test, feature = "serde"))]
1112 pub(crate) fn from_strings(
1113 pattern: impl AsRef<str>,
1114 options: impl AsRef<str>,
1115 ) -> crate::error::Result<Self> {
1116 let mut chars: Vec<_> = options.as_ref().chars().collect();
1117 chars.sort_unstable();
1118 let options: String = chars.into_iter().collect();
1119 Ok(Self {
1120 pattern: pattern.as_ref().to_string().try_into()?,
1121 options: options.try_into()?,
1122 })
1123 }
1124}
1125
1126impl Display for Regex {
1127 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1128 write!(fmt, "/{}/{}", self.pattern, self.options)
1129 }
1130}
1131
1132#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1134pub struct JavaScriptCodeWithScope {
1135 pub code: String,
1137
1138 pub scope: Document,
1140}
1141
1142impl Display for JavaScriptCodeWithScope {
1143 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1144 fmt.write_str(&self.code)
1145 }
1146}
1147
1148#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1150pub struct DbPointer {
1151 pub(crate) namespace: String,
1152 pub(crate) id: oid::ObjectId,
1153}