bson/
bson.rs

1// The MIT License (MIT)
2
3// Copyright (c) 2015 Y. T. Chung <zonyitoo@gmail.com>
4
5// Permission is hereby granted, free of charge, to any person obtaining a copy of
6// this software and associated documentation files (the "Software"), to deal in
7// the Software without restriction, including without limitation the rights to
8// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9// the Software, and to permit persons to whom the Software is furnished to do so,
10// subject to the following conditions:
11
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22//! BSON definition
23
24use 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/// Possible BSON value types.
43#[derive(Clone, Default, PartialEq)]
44pub enum Bson {
45    /// 64-bit binary floating point
46    Double(f64),
47    /// UTF-8 string
48    String(String),
49    /// Array
50    Array(Array),
51    /// Embedded document
52    Document(Document),
53    /// Boolean value
54    Boolean(bool),
55    /// Null value
56    #[default]
57    Null,
58    /// Regular expression
59    RegularExpression(Regex),
60    /// JavaScript code
61    JavaScriptCode(String),
62    /// JavaScript code w/ scope
63    JavaScriptCodeWithScope(JavaScriptCodeWithScope),
64    /// 32-bit signed integer
65    Int32(i32),
66    /// 64-bit signed integer
67    Int64(i64),
68    /// Timestamp
69    Timestamp(Timestamp),
70    /// Binary data
71    Binary(Binary),
72    /// [ObjectId](http://dochub.mongodb.org/core/objectids)
73    ObjectId(oid::ObjectId),
74    /// UTC datetime
75    DateTime(crate::DateTime),
76    /// Symbol (Deprecated)
77    Symbol(String),
78    /// [128-bit decimal floating point](https://github.com/mongodb/specifications/blob/master/source/bson-decimal128/decimal128.rst)
79    Decimal128(Decimal128),
80    /// Undefined value (Deprecated)
81    Undefined,
82    /// Max key
83    MaxKey,
84    /// Min key
85    MinKey,
86    /// DBPointer (Deprecated)
87    DbPointer(DbPointer),
88}
89
90/// Alias for `Vec<Bson>`.
91pub 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                    // There are 2 zero representations, +0 and -0, which
99                    // compare equal but have different bits. We use the +0 hash
100                    // for both so that hash(+0) == hash(-0).
101                    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    /// # Examples
372    ///
373    /// ```
374    /// use std::iter::FromIterator;
375    /// use bson::Bson;
376    ///
377    /// let x: Bson = Bson::from_iter(vec!["lorem", "ipsum", "dolor"]);
378    /// // or
379    /// let x: Bson = vec!["lorem", "ipsum", "dolor"].into_iter().collect();
380    /// ```
381    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    /// Get the [`ElementType`] of this value.
480    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    /// Converts to extended format.
507    /// This function mainly used for [extended JSON format](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/).
508    // TODO RUST-426: Investigate either removing this from the serde implementation or unifying
509    // with the extended JSON implementation.
510    #[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                    // Unwrap safety: timestamps in the guarded range can always be formatted.
577                    "$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    /// Method for converting a given [`Bson`] value to a [`serde::de::Unexpected`] for error
813    /// reporting.
814    #[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()); // placeholder
874                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
894/// Value helpers
895impl Bson {
896    /// If `self` is [`Double`](Bson::Double), return its value as an `f64`. Returns [`None`]
897    /// otherwise.
898    pub fn as_f64(&self) -> Option<f64> {
899        match *self {
900            Bson::Double(v) => Some(v),
901            _ => None,
902        }
903    }
904
905    /// If `self` is [`String`](Bson::String), return its value as a `&str`. Returns [`None`]
906    /// otherwise.
907    pub fn as_str(&self) -> Option<&str> {
908        match *self {
909            Bson::String(ref s) => Some(s),
910            _ => None,
911        }
912    }
913
914    /// If `self` is [`String`](Bson::String), return a mutable reference to its value as a [`str`].
915    /// Returns [`None`] otherwise.
916    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    /// If `self` is [`Array`](Bson::Array), return its value. Returns [`None`] otherwise.
924    pub fn as_array(&self) -> Option<&Array> {
925        match *self {
926            Bson::Array(ref v) => Some(v),
927            _ => None,
928        }
929    }
930
931    /// If `self` is [`Array`](Bson::Array), return a mutable reference to its value. Returns
932    /// [`None`] otherwise.
933    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    /// If `self` is [`Document`](Bson::Document), return its value. Returns [`None`] otherwise.
941    pub fn as_document(&self) -> Option<&Document> {
942        match *self {
943            Bson::Document(ref v) => Some(v),
944            _ => None,
945        }
946    }
947
948    /// If `self` is [`Document`](Bson::Document), return a mutable reference to its value. Returns
949    /// [`None`] otherwise.
950    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    /// If `self` is [`Boolean`](Bson::Boolean), return its value. Returns [`None`] otherwise.
958    pub fn as_bool(&self) -> Option<bool> {
959        match *self {
960            Bson::Boolean(v) => Some(v),
961            _ => None,
962        }
963    }
964
965    /// If `self` is [`Int32`](Bson::Int32), return its value. Returns [`None`] otherwise.
966    pub fn as_i32(&self) -> Option<i32> {
967        match *self {
968            Bson::Int32(v) => Some(v),
969            _ => None,
970        }
971    }
972
973    /// If `self` is [`Int64`](Bson::Int64), return its value. Returns [`None`] otherwise.
974    pub fn as_i64(&self) -> Option<i64> {
975        match *self {
976            Bson::Int64(v) => Some(v),
977            _ => None,
978        }
979    }
980
981    /// If `self` is [`ObjectId`](Bson::ObjectId), return its value. Returns [`None`] otherwise.
982    pub fn as_object_id(&self) -> Option<oid::ObjectId> {
983        match *self {
984            Bson::ObjectId(v) => Some(v),
985            _ => None,
986        }
987    }
988
989    /// If `self` is [`ObjectId`](Bson::ObjectId), return a mutable reference to its value. Returns
990    /// [`None`] otherwise.
991    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    /// If `self` is [`DateTime`](Bson::DateTime), return its value. Returns [`None`] otherwise.
999    pub fn as_datetime(&self) -> Option<&crate::DateTime> {
1000        match *self {
1001            Bson::DateTime(ref v) => Some(v),
1002            _ => None,
1003        }
1004    }
1005
1006    /// If `self` is [`DateTime`](Bson::DateTime), return a mutable reference to its value. Returns
1007    /// [`None`] otherwise.
1008    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    /// If `self` is [`Symbol`](Bson::Symbol), return its value. Returns [`None`] otherwise.
1016    pub fn as_symbol(&self) -> Option<&str> {
1017        match *self {
1018            Bson::Symbol(ref v) => Some(v),
1019            _ => None,
1020        }
1021    }
1022
1023    /// If `self` is [`Symbol`](Bson::Symbol), return a mutable reference to its value. Returns
1024    /// [`None`] otherwise.
1025    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    /// If `self` is [`Timestamp`](Bson::Timestamp), return its value. Returns [`None`] otherwise.
1033    pub fn as_timestamp(&self) -> Option<Timestamp> {
1034        match *self {
1035            Bson::Timestamp(timestamp) => Some(timestamp),
1036            _ => None,
1037        }
1038    }
1039
1040    /// If `self` is [`Null`](Bson::Null), return `()`. Returns [`None`] otherwise.
1041    pub fn as_null(&self) -> Option<()> {
1042        match *self {
1043            Bson::Null => Some(()),
1044            _ => None,
1045        }
1046    }
1047
1048    /// If `self` is [`DbPointer`](Bson::DbPointer), return its value.  Returns [`None`] otherwise.
1049    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/// Represents a BSON timestamp value.
1058#[derive(Debug, Eq, Ord, PartialEq, PartialOrd, Clone, Copy, Hash)]
1059pub struct Timestamp {
1060    /// The number of seconds since the Unix epoch.
1061    pub time: u32,
1062
1063    /// An incrementing value to order timestamps with the same number of seconds in the `time`
1064    /// field.
1065    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/// Represents a BSON regular expression value.
1095#[derive(Debug, Clone, Eq, PartialEq, Hash)]
1096pub struct Regex {
1097    /// The regex pattern to match.
1098    pub pattern: CString,
1099
1100    /// The options for the regex.
1101    ///
1102    /// Options are identified by characters, which must be stored in
1103    /// alphabetical order. Valid options are 'i' for case insensitive matching, 'm' for
1104    /// multiline matching, 'x' for verbose mode, 'l' to make \w, \W, etc. locale dependent,
1105    /// 's' for dotall mode ('.' matches everything), and 'u' to make \w, \W, etc. match
1106    /// unicode.
1107    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/// Represents a BSON code with scope value.
1133#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1134pub struct JavaScriptCodeWithScope {
1135    /// The JavaScript code.
1136    pub code: String,
1137
1138    /// The scope document containing variable bindings.
1139    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/// Represents a DBPointer. (Deprecated)
1149#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1150pub struct DbPointer {
1151    pub(crate) namespace: String,
1152    pub(crate) id: oid::ObjectId,
1153}