Coverage Report

Created: 2025-09-05 06:11

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