bson/raw/
bson_ref.rs

1use std::convert::{TryFrom, TryInto};
2
3use serde::{ser::SerializeStruct, Deserialize, Serialize};
4use serde_bytes::Bytes;
5
6use super::{
7    bson::RawBson,
8    serde::{bson_visitor::OwnedOrBorrowedRawBsonVisitor, OwnedOrBorrowedRawBson},
9    Error,
10    RawArray,
11    RawDocument,
12    Result,
13};
14use crate::{
15    base64,
16    extjson,
17    oid::{self, ObjectId},
18    raw::{RawJavaScriptCodeWithScope, RAW_BSON_NEWTYPE},
19    spec::{BinarySubtype, ElementType},
20    Binary,
21    Bson,
22    DbPointer,
23    Decimal128,
24    RawArrayBuf,
25    RawDocumentBuf,
26    Regex,
27    Timestamp,
28};
29
30/// A BSON value referencing raw bytes stored elsewhere.
31#[derive(Debug, Clone, Copy, PartialEq)]
32pub enum RawBsonRef<'a> {
33    /// 64-bit binary floating point
34    Double(f64),
35    /// UTF-8 string
36    String(&'a str),
37    /// Array
38    Array(&'a RawArray),
39    /// Embedded document
40    Document(&'a RawDocument),
41    /// Boolean value
42    Boolean(bool),
43    /// Null value
44    Null,
45    /// Regular expression
46    RegularExpression(RawRegexRef<'a>),
47    /// JavaScript code
48    JavaScriptCode(&'a str),
49    /// JavaScript code w/ scope
50    JavaScriptCodeWithScope(RawJavaScriptCodeWithScopeRef<'a>),
51    /// 32-bit signed integer
52    Int32(i32),
53    /// 64-bit signed integer
54    Int64(i64),
55    /// Timestamp
56    Timestamp(Timestamp),
57    /// Binary data
58    Binary(RawBinaryRef<'a>),
59    /// [ObjectId](http://dochub.mongodb.org/core/objectids)
60    ObjectId(oid::ObjectId),
61    /// UTC datetime
62    DateTime(crate::DateTime),
63    /// Symbol (Deprecated)
64    Symbol(&'a str),
65    /// [128-bit decimal floating point](https://github.com/mongodb/specifications/blob/master/source/bson-decimal128/decimal128.rst)
66    Decimal128(Decimal128),
67    /// Undefined value (Deprecated)
68    Undefined,
69    /// Max key
70    MaxKey,
71    /// Min key
72    MinKey,
73    /// DBPointer (Deprecated)
74    DbPointer(RawDbPointerRef<'a>),
75}
76
77impl<'a> RawBsonRef<'a> {
78    /// Get the [`ElementType`] of this value.
79    pub fn element_type(&self) -> ElementType {
80        match *self {
81            RawBsonRef::Double(..) => ElementType::Double,
82            RawBsonRef::String(..) => ElementType::String,
83            RawBsonRef::Array(..) => ElementType::Array,
84            RawBsonRef::Document(..) => ElementType::EmbeddedDocument,
85            RawBsonRef::Boolean(..) => ElementType::Boolean,
86            RawBsonRef::Null => ElementType::Null,
87            RawBsonRef::RegularExpression(..) => ElementType::RegularExpression,
88            RawBsonRef::JavaScriptCode(..) => ElementType::JavaScriptCode,
89            RawBsonRef::JavaScriptCodeWithScope(..) => ElementType::JavaScriptCodeWithScope,
90            RawBsonRef::Int32(..) => ElementType::Int32,
91            RawBsonRef::Int64(..) => ElementType::Int64,
92            RawBsonRef::Timestamp(..) => ElementType::Timestamp,
93            RawBsonRef::Binary(..) => ElementType::Binary,
94            RawBsonRef::ObjectId(..) => ElementType::ObjectId,
95            RawBsonRef::DateTime(..) => ElementType::DateTime,
96            RawBsonRef::Symbol(..) => ElementType::Symbol,
97            RawBsonRef::Decimal128(..) => ElementType::Decimal128,
98            RawBsonRef::Undefined => ElementType::Undefined,
99            RawBsonRef::MaxKey => ElementType::MaxKey,
100            RawBsonRef::MinKey => ElementType::MinKey,
101            RawBsonRef::DbPointer(..) => ElementType::DbPointer,
102        }
103    }
104
105    /// Gets the `f64` that's referenced or returns [`None`] if the referenced value isn't a BSON
106    /// double.
107    pub fn as_f64(self) -> Option<f64> {
108        match self {
109            RawBsonRef::Double(d) => Some(d),
110            _ => None,
111        }
112    }
113
114    /// Gets the `&str` that's referenced or returns [`None`] if the referenced value isn't a BSON
115    /// String.
116    pub fn as_str(self) -> Option<&'a str> {
117        match self {
118            RawBsonRef::String(s) => Some(s),
119            _ => None,
120        }
121    }
122
123    /// Gets the [`RawArray`] that's referenced or returns [`None`] if the referenced value
124    /// isn't a BSON array.
125    pub fn as_array(self) -> Option<&'a RawArray> {
126        match self {
127            RawBsonRef::Array(v) => Some(v),
128            _ => None,
129        }
130    }
131
132    /// Gets the [`RawDocument`] that's referenced or returns [`None`] if the referenced value
133    /// isn't a BSON document.
134    pub fn as_document(self) -> Option<&'a RawDocument> {
135        match self {
136            RawBsonRef::Document(v) => Some(v),
137            _ => None,
138        }
139    }
140
141    /// Gets the `bool` that's referenced or returns [`None`] if the referenced value isn't a BSON
142    /// boolean.
143    pub fn as_bool(self) -> Option<bool> {
144        match self {
145            RawBsonRef::Boolean(v) => Some(v),
146            _ => None,
147        }
148    }
149
150    /// Gets the `i32` that's referenced or returns [`None`] if the referenced value isn't a BSON
151    /// Int32.
152    pub fn as_i32(self) -> Option<i32> {
153        match self {
154            RawBsonRef::Int32(v) => Some(v),
155            _ => None,
156        }
157    }
158
159    /// Gets the `i64` that's referenced or returns [`None`] if the referenced value isn't a BSON
160    /// Int64.
161    pub fn as_i64(self) -> Option<i64> {
162        match self {
163            RawBsonRef::Int64(v) => Some(v),
164            _ => None,
165        }
166    }
167
168    /// Gets the [`crate::oid::ObjectId`] that's referenced or returns [`None`] if the referenced
169    /// value isn't a BSON ObjectID.
170    pub fn as_object_id(self) -> Option<oid::ObjectId> {
171        match self {
172            RawBsonRef::ObjectId(v) => Some(v),
173            _ => None,
174        }
175    }
176
177    /// Gets the [`RawBinaryRef`] that's referenced or returns [`None`] if the referenced value
178    /// isn't a BSON binary.
179    pub fn as_binary(self) -> Option<RawBinaryRef<'a>> {
180        match self {
181            RawBsonRef::Binary(v) => Some(v),
182            _ => None,
183        }
184    }
185
186    /// Gets the [`RawRegexRef`] that's referenced or returns [`None`] if the referenced value isn't
187    /// a BSON regular expression.
188    pub fn as_regex(self) -> Option<RawRegexRef<'a>> {
189        match self {
190            RawBsonRef::RegularExpression(v) => Some(v),
191            _ => None,
192        }
193    }
194
195    /// Gets the [`crate::DateTime`] that's referenced or returns [`None`] if the referenced value
196    /// isn't a BSON datetime.
197    pub fn as_datetime(self) -> Option<crate::DateTime> {
198        match self {
199            RawBsonRef::DateTime(v) => Some(v),
200            _ => None,
201        }
202    }
203
204    /// Gets the symbol that's referenced or returns [`None`] if the referenced value isn't a BSON
205    /// symbol.
206    pub fn as_symbol(self) -> Option<&'a str> {
207        match self {
208            RawBsonRef::Symbol(v) => Some(v),
209            _ => None,
210        }
211    }
212
213    /// Gets the [`crate::Timestamp`] that's referenced or returns [`None`] if the referenced value
214    /// isn't a BSON timestamp.
215    pub fn as_timestamp(self) -> Option<Timestamp> {
216        match self {
217            RawBsonRef::Timestamp(timestamp) => Some(timestamp),
218            _ => None,
219        }
220    }
221
222    /// Gets the null value that's referenced or returns [`None`] if the referenced value isn't a
223    /// BSON null.
224    pub fn as_null(self) -> Option<()> {
225        match self {
226            RawBsonRef::Null => Some(()),
227            _ => None,
228        }
229    }
230
231    /// Gets the [`RawDbPointerRef`] that's referenced or returns [`None`] if the referenced value
232    /// isn't a BSON DB pointer.
233    pub fn as_db_pointer(self) -> Option<RawDbPointerRef<'a>> {
234        match self {
235            RawBsonRef::DbPointer(d) => Some(d),
236            _ => None,
237        }
238    }
239
240    /// Gets the code that's referenced or returns [`None`] if the referenced value isn't a BSON
241    /// JavaScript.
242    pub fn as_javascript(self) -> Option<&'a str> {
243        match self {
244            RawBsonRef::JavaScriptCode(s) => Some(s),
245            _ => None,
246        }
247    }
248
249    /// Gets the [`RawJavaScriptCodeWithScope`] that's referenced or returns [`None`] if the
250    /// referenced value isn't a BSON JavaScript with scope.
251    pub fn as_javascript_with_scope(self) -> Option<RawJavaScriptCodeWithScopeRef<'a>> {
252        match self {
253            RawBsonRef::JavaScriptCodeWithScope(s) => Some(s),
254            _ => None,
255        }
256    }
257
258    /// Convert this [`RawBsonRef`] to the equivalent [`RawBson`].
259    pub fn to_raw_bson(self) -> RawBson {
260        match self {
261            RawBsonRef::Double(d) => RawBson::Double(d),
262            RawBsonRef::String(s) => RawBson::String(s.to_string()),
263            RawBsonRef::Array(a) => RawBson::Array(a.to_owned()),
264            RawBsonRef::Document(d) => RawBson::Document(d.to_owned()),
265            RawBsonRef::Boolean(b) => RawBson::Boolean(b),
266            RawBsonRef::Null => RawBson::Null,
267            RawBsonRef::RegularExpression(re) => {
268                RawBson::RegularExpression(Regex::new(re.pattern, re.options))
269            }
270            RawBsonRef::JavaScriptCode(c) => RawBson::JavaScriptCode(c.to_owned()),
271            RawBsonRef::JavaScriptCodeWithScope(c_w_s) => {
272                RawBson::JavaScriptCodeWithScope(RawJavaScriptCodeWithScope {
273                    code: c_w_s.code.to_string(),
274                    scope: c_w_s.scope.to_owned(),
275                })
276            }
277            RawBsonRef::Int32(i) => RawBson::Int32(i),
278            RawBsonRef::Int64(i) => RawBson::Int64(i),
279            RawBsonRef::Timestamp(t) => RawBson::Timestamp(t),
280            RawBsonRef::Binary(b) => RawBson::Binary(Binary {
281                bytes: b.bytes.to_vec(),
282                subtype: b.subtype,
283            }),
284            RawBsonRef::ObjectId(o) => RawBson::ObjectId(o),
285            RawBsonRef::DateTime(dt) => RawBson::DateTime(dt),
286            RawBsonRef::Symbol(s) => RawBson::Symbol(s.to_string()),
287            RawBsonRef::Decimal128(d) => RawBson::Decimal128(d),
288            RawBsonRef::Undefined => RawBson::Undefined,
289            RawBsonRef::MaxKey => RawBson::MaxKey,
290            RawBsonRef::MinKey => RawBson::MinKey,
291            RawBsonRef::DbPointer(d) => RawBson::DbPointer(DbPointer {
292                namespace: d.namespace.to_string(),
293                id: d.id,
294            }),
295        }
296    }
297}
298
299impl<'de: 'a, 'a> Deserialize<'de> for RawBsonRef<'a> {
300    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
301    where
302        D: serde::Deserializer<'de>,
303    {
304        match deserializer
305            .deserialize_newtype_struct(RAW_BSON_NEWTYPE, OwnedOrBorrowedRawBsonVisitor)?
306        {
307            OwnedOrBorrowedRawBson::Borrowed(b) => Ok(b),
308            o => Err(serde::de::Error::custom(format!(
309                "RawBson must be deserialized from borrowed content, instead got {:?}",
310                o
311            ))),
312        }
313    }
314}
315
316impl Serialize for RawBsonRef<'_> {
317    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
318    where
319        S: serde::Serializer,
320    {
321        match self {
322            RawBsonRef::Double(v) => serializer.serialize_f64(*v),
323            RawBsonRef::String(v) => serializer.serialize_str(v),
324            RawBsonRef::Array(v) => v.serialize(serializer),
325            RawBsonRef::Document(v) => v.serialize(serializer),
326            RawBsonRef::Boolean(v) => serializer.serialize_bool(*v),
327            RawBsonRef::Null => serializer.serialize_unit(),
328            RawBsonRef::Int32(v) => serializer.serialize_i32(*v),
329            RawBsonRef::Int64(v) => serializer.serialize_i64(*v),
330            RawBsonRef::ObjectId(oid) => oid.serialize(serializer),
331            RawBsonRef::DateTime(dt) => dt.serialize(serializer),
332            RawBsonRef::Binary(b) => b.serialize(serializer),
333            RawBsonRef::JavaScriptCode(c) => {
334                let mut state = serializer.serialize_struct("$code", 1)?;
335                state.serialize_field("$code", c)?;
336                state.end()
337            }
338            RawBsonRef::JavaScriptCodeWithScope(code_w_scope) => code_w_scope.serialize(serializer),
339            RawBsonRef::DbPointer(dbp) => dbp.serialize(serializer),
340            RawBsonRef::Symbol(s) => {
341                let mut state = serializer.serialize_struct("$symbol", 1)?;
342                state.serialize_field("$symbol", s)?;
343                state.end()
344            }
345            RawBsonRef::RegularExpression(re) => re.serialize(serializer),
346            RawBsonRef::Timestamp(t) => t.serialize(serializer),
347            RawBsonRef::Decimal128(d) => d.serialize(serializer),
348            RawBsonRef::Undefined => {
349                let mut state = serializer.serialize_struct("$undefined", 1)?;
350                state.serialize_field("$undefined", &true)?;
351                state.end()
352            }
353            RawBsonRef::MaxKey => {
354                let mut state = serializer.serialize_struct("$maxKey", 1)?;
355                state.serialize_field("$maxKey", &1)?;
356                state.end()
357            }
358            RawBsonRef::MinKey => {
359                let mut state = serializer.serialize_struct("$minKey", 1)?;
360                state.serialize_field("$minKey", &1)?;
361                state.end()
362            }
363        }
364    }
365}
366
367impl<'a> TryFrom<RawBsonRef<'a>> for Bson {
368    type Error = Error;
369
370    fn try_from(rawbson: RawBsonRef<'a>) -> Result<Bson> {
371        rawbson.to_raw_bson().try_into()
372    }
373}
374
375impl From<i32> for RawBsonRef<'_> {
376    fn from(i: i32) -> Self {
377        RawBsonRef::Int32(i)
378    }
379}
380
381impl From<i64> for RawBsonRef<'_> {
382    fn from(i: i64) -> Self {
383        RawBsonRef::Int64(i)
384    }
385}
386
387impl<'a> From<&'a str> for RawBsonRef<'a> {
388    fn from(s: &'a str) -> Self {
389        RawBsonRef::String(s)
390    }
391}
392
393impl From<f64> for RawBsonRef<'_> {
394    fn from(f: f64) -> Self {
395        RawBsonRef::Double(f)
396    }
397}
398
399impl From<bool> for RawBsonRef<'_> {
400    fn from(b: bool) -> Self {
401        RawBsonRef::Boolean(b)
402    }
403}
404
405impl<'a> From<&'a RawDocumentBuf> for RawBsonRef<'a> {
406    fn from(d: &'a RawDocumentBuf) -> Self {
407        RawBsonRef::Document(d.as_ref())
408    }
409}
410
411impl<'a> From<&'a RawDocument> for RawBsonRef<'a> {
412    fn from(d: &'a RawDocument) -> Self {
413        RawBsonRef::Document(d)
414    }
415}
416
417impl<'a> From<&'a RawArray> for RawBsonRef<'a> {
418    fn from(a: &'a RawArray) -> Self {
419        RawBsonRef::Array(a)
420    }
421}
422
423impl<'a> From<&'a RawArrayBuf> for RawBsonRef<'a> {
424    fn from(a: &'a RawArrayBuf) -> Self {
425        RawBsonRef::Array(a)
426    }
427}
428
429impl From<crate::DateTime> for RawBsonRef<'_> {
430    fn from(dt: crate::DateTime) -> Self {
431        RawBsonRef::DateTime(dt)
432    }
433}
434
435impl From<Timestamp> for RawBsonRef<'_> {
436    fn from(ts: Timestamp) -> Self {
437        RawBsonRef::Timestamp(ts)
438    }
439}
440
441impl From<ObjectId> for RawBsonRef<'_> {
442    fn from(oid: ObjectId) -> Self {
443        RawBsonRef::ObjectId(oid)
444    }
445}
446
447impl From<Decimal128> for RawBsonRef<'_> {
448    fn from(d: Decimal128) -> Self {
449        RawBsonRef::Decimal128(d)
450    }
451}
452
453/// A BSON binary value referencing raw bytes stored elsewhere.
454#[derive(Clone, Copy, Debug, PartialEq)]
455pub struct RawBinaryRef<'a> {
456    /// The subtype of the binary value.
457    pub subtype: BinarySubtype,
458
459    /// The binary bytes.
460    pub bytes: &'a [u8],
461}
462
463impl RawBinaryRef<'_> {
464    /// Copy the contents into a [`Binary`].
465    pub fn to_binary(&self) -> Binary {
466        Binary {
467            subtype: self.subtype,
468            bytes: self.bytes.to_owned(),
469        }
470    }
471
472    pub(crate) fn len(&self) -> i32 {
473        match self.subtype {
474            BinarySubtype::BinaryOld => self.bytes.len() as i32 + 4,
475            _ => self.bytes.len() as i32,
476        }
477    }
478}
479
480impl<'de: 'a, 'a> Deserialize<'de> for RawBinaryRef<'a> {
481    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
482    where
483        D: serde::Deserializer<'de>,
484    {
485        match RawBsonRef::deserialize(deserializer)? {
486            RawBsonRef::Binary(b) => Ok(b),
487            c => Err(serde::de::Error::custom(format!(
488                "expected binary, but got {:?} instead",
489                c
490            ))),
491        }
492    }
493}
494
495impl Serialize for RawBinaryRef<'_> {
496    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
497    where
498        S: serde::Serializer,
499    {
500        if let BinarySubtype::Generic = self.subtype {
501            serializer.serialize_bytes(self.bytes)
502        } else if !serializer.is_human_readable() {
503            #[derive(Serialize)]
504            struct BorrowedBinary<'a> {
505                bytes: &'a Bytes,
506
507                #[serde(rename = "subType")]
508                subtype: u8,
509            }
510
511            let mut state = serializer.serialize_struct("$binary", 1)?;
512            let body = BorrowedBinary {
513                bytes: Bytes::new(self.bytes),
514                subtype: self.subtype.into(),
515            };
516            state.serialize_field("$binary", &body)?;
517            state.end()
518        } else {
519            let mut state = serializer.serialize_struct("$binary", 1)?;
520            let body = extjson::models::BinaryBody {
521                base64: base64::encode(self.bytes),
522                subtype: hex::encode([self.subtype.into()]),
523            };
524            state.serialize_field("$binary", &body)?;
525            state.end()
526        }
527    }
528}
529
530impl<'a> From<RawBinaryRef<'a>> for RawBsonRef<'a> {
531    fn from(b: RawBinaryRef<'a>) -> Self {
532        RawBsonRef::Binary(b)
533    }
534}
535
536impl<'a> From<&'a Binary> for RawBsonRef<'a> {
537    fn from(bin: &'a Binary) -> Self {
538        bin.as_raw_binary().into()
539    }
540}
541
542/// A BSON regex referencing raw bytes stored elsewhere.
543#[derive(Clone, Copy, Debug, PartialEq)]
544pub struct RawRegexRef<'a> {
545    /// The regex pattern to match.
546    pub pattern: &'a str,
547
548    /// The options for the regex.
549    ///
550    /// Options are identified by characters, which must be stored in
551    /// alphabetical order. Valid options are 'i' for case insensitive matching, 'm' for
552    /// multiline matching, 'x' for verbose mode, 'l' to make \w, \W, etc. locale dependent,
553    /// 's' for dotall mode ('.' matches everything), and 'u' to make \w, \W, etc. match
554    /// unicode.
555    pub options: &'a str,
556}
557
558impl<'de: 'a, 'a> Deserialize<'de> for RawRegexRef<'a> {
559    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
560    where
561        D: serde::Deserializer<'de>,
562    {
563        match RawBsonRef::deserialize(deserializer)? {
564            RawBsonRef::RegularExpression(b) => Ok(b),
565            c => Err(serde::de::Error::custom(format!(
566                "expected Regex, but got {:?} instead",
567                c
568            ))),
569        }
570    }
571}
572
573impl Serialize for RawRegexRef<'_> {
574    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
575    where
576        S: serde::Serializer,
577    {
578        #[derive(Serialize)]
579        struct BorrowedRegexBody<'a> {
580            pattern: &'a str,
581            options: &'a str,
582        }
583
584        let mut state = serializer.serialize_struct("$regularExpression", 1)?;
585        let body = BorrowedRegexBody {
586            pattern: self.pattern,
587            options: self.options,
588        };
589        state.serialize_field("$regularExpression", &body)?;
590        state.end()
591    }
592}
593
594impl<'a> From<RawRegexRef<'a>> for RawBsonRef<'a> {
595    fn from(re: RawRegexRef<'a>) -> Self {
596        RawBsonRef::RegularExpression(re)
597    }
598}
599
600/// A BSON "code with scope" value referencing raw bytes stored elsewhere.
601#[derive(Clone, Copy, Debug, PartialEq)]
602pub struct RawJavaScriptCodeWithScopeRef<'a> {
603    /// The JavaScript code.
604    pub code: &'a str,
605
606    /// The scope document containing variable bindings.
607    pub scope: &'a RawDocument,
608}
609
610impl RawJavaScriptCodeWithScopeRef<'_> {
611    pub(crate) fn len(self) -> i32 {
612        4 + 4 + self.code.len() as i32 + 1 + self.scope.as_bytes().len() as i32
613    }
614}
615
616impl<'de: 'a, 'a> Deserialize<'de> for RawJavaScriptCodeWithScopeRef<'a> {
617    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
618    where
619        D: serde::Deserializer<'de>,
620    {
621        match RawBsonRef::deserialize(deserializer)? {
622            RawBsonRef::JavaScriptCodeWithScope(b) => Ok(b),
623            c => Err(serde::de::Error::custom(format!(
624                "expected CodeWithScope, but got {:?} instead",
625                c
626            ))),
627        }
628    }
629}
630
631impl Serialize for RawJavaScriptCodeWithScopeRef<'_> {
632    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
633    where
634        S: serde::Serializer,
635    {
636        let mut state = serializer.serialize_struct("$codeWithScope", 2)?;
637        state.serialize_field("$code", &self.code)?;
638        state.serialize_field("$scope", &self.scope)?;
639        state.end()
640    }
641}
642
643impl<'a> From<RawJavaScriptCodeWithScopeRef<'a>> for RawBsonRef<'a> {
644    fn from(code_w_scope: RawJavaScriptCodeWithScopeRef<'a>) -> Self {
645        RawBsonRef::JavaScriptCodeWithScope(code_w_scope)
646    }
647}
648
649/// A BSON DB pointer value referencing raw bytes stored elesewhere.
650#[derive(Debug, Clone, Copy, PartialEq)]
651pub struct RawDbPointerRef<'a> {
652    pub(crate) namespace: &'a str,
653    pub(crate) id: ObjectId,
654}
655
656impl<'de: 'a, 'a> Deserialize<'de> for RawDbPointerRef<'a> {
657    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
658    where
659        D: serde::Deserializer<'de>,
660    {
661        match RawBsonRef::deserialize(deserializer)? {
662            RawBsonRef::DbPointer(b) => Ok(b),
663            c => Err(serde::de::Error::custom(format!(
664                "expected DbPointer, but got {:?} instead",
665                c
666            ))),
667        }
668    }
669}
670
671impl Serialize for RawDbPointerRef<'_> {
672    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
673    where
674        S: serde::Serializer,
675    {
676        #[derive(Serialize)]
677        struct BorrowedDbPointerBody<'a> {
678            #[serde(rename = "$ref")]
679            ref_ns: &'a str,
680
681            #[serde(rename = "$id")]
682            id: ObjectId,
683        }
684
685        let mut state = serializer.serialize_struct("$dbPointer", 1)?;
686        let body = BorrowedDbPointerBody {
687            ref_ns: self.namespace,
688            id: self.id,
689        };
690        state.serialize_field("$dbPointer", &body)?;
691        state.end()
692    }
693}