bson/raw/
document.rs

1use std::{
2    borrow::Cow,
3    convert::{TryFrom, TryInto},
4};
5
6use serde::{ser::SerializeMap, Deserialize, Serialize};
7
8use crate::{
9    de::MIN_BSON_DOCUMENT_SIZE,
10    raw::{error::ErrorKind, serde::OwnedOrBorrowedRawDocument, RAW_DOCUMENT_NEWTYPE},
11    DateTime,
12    Timestamp,
13};
14
15use super::{
16    error::{ValueAccessError, ValueAccessErrorKind, ValueAccessResult},
17    i32_from_slice,
18    iter::Iter,
19    try_to_str,
20    Error,
21    RawArray,
22    RawBinaryRef,
23    RawBsonRef,
24    RawDocumentBuf,
25    RawIter,
26    RawRegexRef,
27    Result,
28};
29use crate::{oid::ObjectId, spec::ElementType, Document};
30
31/// A slice of a BSON document (akin to [`std::str`]). This can be created from a
32/// [`RawDocumentBuf`] or any type that contains valid BSON data, including static binary literals,
33/// [`Vec<u8>`](std::vec::Vec), or arrays.
34///
35/// This is an _unsized_ type, meaning that it must always be used behind a pointer like `&`. For an
36/// owned version of this type, see [`RawDocumentBuf`].
37///
38/// Accessing elements within a [`RawDocument`] is similar to element access in [`crate::Document`],
39/// but because the contents are parsed during iteration instead of at creation time, format errors
40/// can happen at any time during use.
41///
42/// Iterating over a [`RawDocument`] yields either an error or a key-value pair that borrows from
43/// the original document without making any additional allocations.
44/// ```
45/// # use bson::raw::{Error};
46/// use bson::raw::RawDocument;
47///
48/// let doc = RawDocument::from_bytes(b"\x13\x00\x00\x00\x02hi\x00\x06\x00\x00\x00y'all\x00\x00")?;
49/// let mut iter = doc.into_iter();
50/// let (key, value) = iter.next().unwrap()?;
51/// assert_eq!(key, "hi");
52/// assert_eq!(value.as_str(), Some("y'all"));
53/// assert!(iter.next().is_none());
54/// # Ok::<(), Error>(())
55/// ```
56///
57/// Individual elements can be accessed using [`RawDocument::get`] or any of
58/// the type-specific getters, such as [`RawDocument::get_object_id`] or
59/// [`RawDocument::get_str`]. Note that accessing elements is an O(N) operation, as it
60/// requires iterating through the document from the beginning to find the requested key.
61///
62/// ```
63/// use bson::raw::RawDocument;
64///
65/// let doc = RawDocument::from_bytes(b"\x13\x00\x00\x00\x02hi\x00\x06\x00\x00\x00y'all\x00\x00")?;
66/// assert_eq!(doc.get_str("hi")?, "y'all");
67/// # Ok::<(), Box<dyn std::error::Error>>(())
68/// ```
69#[derive(PartialEq)]
70#[repr(transparent)]
71pub struct RawDocument {
72    data: [u8],
73}
74
75impl RawDocument {
76    /// Constructs a new [`RawDocument`], validating _only_ the
77    /// following invariants:
78    ///   * `data` is at least five bytes long (the minimum for a valid BSON document)
79    ///   * the initial four bytes of `data` accurately represent the length of the bytes as
80    ///     required by the BSON spec.
81    ///   * the last byte of `data` is a 0
82    ///
83    /// Note that the internal structure of the bytes representing the
84    /// BSON elements is _not_ validated at all by this method. If the
85    /// bytes do not conform to the BSON spec, then method calls on
86    /// the [`RawDocument`] will return Errors where appropriate.
87    ///
88    /// ```
89    /// use bson::raw::RawDocument;
90    ///
91    /// let doc = RawDocument::from_bytes(b"\x05\0\0\0\0")?;
92    /// # Ok::<(), bson::raw::Error>(())
93    /// ```
94    pub fn from_bytes<D: AsRef<[u8]> + ?Sized>(data: &D) -> Result<&RawDocument> {
95        let data = data.as_ref();
96
97        if data.len() < 5 {
98            return Err(Error {
99                key: None,
100                kind: ErrorKind::MalformedValue {
101                    message: "document too short".into(),
102                },
103            });
104        }
105
106        let length = i32_from_slice(data)?;
107
108        if data.len() as i32 != length {
109            return Err(Error {
110                key: None,
111                kind: ErrorKind::MalformedValue {
112                    message: "document length incorrect".into(),
113                },
114            });
115        }
116
117        if data[data.len() - 1] != 0 {
118            return Err(Error {
119                key: None,
120                kind: ErrorKind::MalformedValue {
121                    message: "document not null-terminated".into(),
122                },
123            });
124        }
125
126        Ok(RawDocument::new_unchecked(data))
127    }
128
129    /// Creates a new [`RawDocument`] referencing the provided data slice.
130    pub(crate) fn new_unchecked<D: AsRef<[u8]> + ?Sized>(data: &D) -> &RawDocument {
131        // SAFETY:
132        //
133        // Dereferencing a raw pointer requires unsafe due to the potential that the pointer is
134        // null, dangling, or misaligned. We know the pointer is not null or dangling due to the
135        // fact that it's created by a safe reference. Converting &[u8] to *const [u8] will be
136        // properly aligned due to them being references to the same type, and converting *const
137        // [u8] to *const RawDocument is aligned due to the fact that the only field in a
138        // RawDocument is a [u8] and it is #[repr(transparent), meaning the structs are represented
139        // identically at the byte level.
140        unsafe { &*(data.as_ref() as *const [u8] as *const RawDocument) }
141    }
142
143    /// Creates a new [`RawDocumentBuf`] with an owned copy of the BSON bytes.
144    ///
145    /// ```
146    /// use bson::raw::{RawDocument, RawDocumentBuf, Error};
147    ///
148    /// let data = b"\x05\0\0\0\0";
149    /// let doc_ref = RawDocument::from_bytes(data)?;
150    /// let doc: RawDocumentBuf = doc_ref.to_raw_document_buf();
151    /// # Ok::<(), Error>(())
152    pub fn to_raw_document_buf(&self) -> RawDocumentBuf {
153        // unwrap is ok here because we already verified the bytes in `RawDocumentRef::new`
154        RawDocumentBuf::from_bytes(self.data.to_owned()).unwrap()
155    }
156
157    /// Gets a reference to the value corresponding to the given key by iterating until the key is
158    /// found.
159    ///
160    /// ```
161    /// # use bson::raw::Error;
162    /// use bson::{rawdoc, oid::ObjectId};
163    ///
164    /// let doc = rawdoc! {
165    ///     "_id": ObjectId::new(),
166    ///     "f64": 2.5,
167    /// };
168    ///
169    /// let element = doc.get("f64")?.expect("finding key f64");
170    /// assert_eq!(element.as_f64(), Some(2.5));
171    /// assert!(doc.get("unknown")?.is_none());
172    /// # Ok::<(), Error>(())
173    /// ```
174    pub fn get(&self, key: impl AsRef<str>) -> Result<Option<RawBsonRef<'_>>> {
175        for elem in RawIter::new(self) {
176            let elem = elem?;
177            if key.as_ref() == elem.key() {
178                return Ok(Some(elem.try_into()?));
179            }
180        }
181        Ok(None)
182    }
183
184    /// Gets an iterator over the elements in the [`RawDocument`] that yields
185    /// `Result<(&str, RawBson<'_>)>`.
186    pub fn iter(&self) -> Iter<'_> {
187        Iter::new(self)
188    }
189
190    /// Gets an iterator over the elements in the [`RawDocument`],
191    /// which yields `Result<RawElement<'_>>` values. These hold a
192    /// reference to the underlying document but do not explicitly
193    /// resolve the values.
194    ///
195    /// This iterator, which underpins the implementation of the
196    /// default iterator, produces `RawElement` objects that hold a
197    /// view onto the document but do not parse out or construct
198    /// values until the `.value()` or `.try_into()` methods are
199    /// called.
200    pub fn iter_elements(&self) -> RawIter<'_> {
201        RawIter::new(self)
202    }
203
204    fn get_with<'a, T>(
205        &'a self,
206        key: impl AsRef<str>,
207        expected_type: ElementType,
208        f: impl FnOnce(RawBsonRef<'a>) -> Option<T>,
209    ) -> ValueAccessResult<T> {
210        let key = key.as_ref();
211
212        let bson = self
213            .get(key)
214            .map_err(|e| ValueAccessError {
215                key: key.to_string(),
216                kind: ValueAccessErrorKind::InvalidBson(e),
217            })?
218            .ok_or(ValueAccessError {
219                key: key.to_string(),
220                kind: ValueAccessErrorKind::NotPresent,
221            })?;
222        match f(bson) {
223            Some(t) => Ok(t),
224            None => Err(ValueAccessError {
225                key: key.to_string(),
226                kind: ValueAccessErrorKind::UnexpectedType {
227                    expected: expected_type,
228                    actual: bson.element_type(),
229                },
230            }),
231        }
232    }
233
234    /// Gets a reference to the BSON double value corresponding to a given key or returns an error
235    /// if the key corresponds to a value which isn't a double.
236    ///
237    /// ```
238    /// # use bson::raw::Error;
239    /// use bson::raw::ValueAccessErrorKind;
240    /// use bson::rawdoc;
241    ///
242    /// let doc = rawdoc! {
243    ///     "bool": true,
244    ///     "f64": 2.5,
245    /// };
246    ///
247    /// assert_eq!(doc.get_f64("f64")?, 2.5);
248    /// assert!(matches!(doc.get_f64("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. }));
249    /// assert!(matches!(doc.get_f64("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
250    /// # Ok::<(), Box<dyn std::error::Error>>(())
251    /// ```
252    pub fn get_f64(&self, key: impl AsRef<str>) -> ValueAccessResult<f64> {
253        self.get_with(key, ElementType::Double, RawBsonRef::as_f64)
254    }
255
256    /// Gets a reference to the string value corresponding to a given key or returns an error if the
257    /// key corresponds to a value which isn't a string.
258    ///
259    /// ```
260    /// use bson::{rawdoc, raw::ValueAccessErrorKind};
261    ///
262    /// let doc = rawdoc! {
263    ///     "string": "hello",
264    ///     "bool": true,
265    /// };
266    ///
267    /// assert_eq!(doc.get_str("string")?, "hello");
268    /// assert!(matches!(doc.get_str("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. }));
269    /// assert!(matches!(doc.get_str("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
270    /// # Ok::<(), Box<dyn std::error::Error>>(())
271    /// ```
272    pub fn get_str(&self, key: impl AsRef<str>) -> ValueAccessResult<&'_ str> {
273        self.get_with(key, ElementType::String, RawBsonRef::as_str)
274    }
275
276    /// Gets a reference to the document value corresponding to a given key or returns an error if
277    /// the key corresponds to a value which isn't a document.
278    ///
279    /// ```
280    /// # use bson::raw::Error;
281    /// use bson::{rawdoc, raw::ValueAccessErrorKind};
282    ///
283    /// let doc = rawdoc! {
284    ///     "doc": { "key": "value"},
285    ///     "bool": true,
286    /// };
287    ///
288    /// assert_eq!(doc.get_document("doc")?.get_str("key")?, "value");
289    /// assert!(matches!(doc.get_document("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. }));
290    /// assert!(matches!(doc.get_document("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
291    /// # Ok::<(), Box<dyn std::error::Error>>(())
292    /// ```
293    pub fn get_document(&self, key: impl AsRef<str>) -> ValueAccessResult<&'_ RawDocument> {
294        self.get_with(key, ElementType::EmbeddedDocument, RawBsonRef::as_document)
295    }
296
297    /// Gets a reference to the array value corresponding to a given key or returns an error if
298    /// the key corresponds to a value which isn't an array.
299    ///
300    /// ```
301    /// use bson::{rawdoc, raw::ValueAccessErrorKind};
302    ///
303    /// let doc = rawdoc! {
304    ///     "array": [true, 3],
305    ///     "bool": true,
306    /// };
307    ///
308    /// let mut arr_iter = doc.get_array("array")?.into_iter();
309    /// let _: bool = arr_iter.next().unwrap()?.as_bool().unwrap();
310    /// let _: i32 = arr_iter.next().unwrap()?.as_i32().unwrap();
311    ///
312    /// assert!(arr_iter.next().is_none());
313    /// assert!(doc.get_array("bool").is_err());
314    /// assert!(matches!(doc.get_array("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
315    /// # Ok::<(), Box<dyn std::error::Error>>(())
316    /// ```
317    pub fn get_array(&self, key: impl AsRef<str>) -> ValueAccessResult<&'_ RawArray> {
318        self.get_with(key, ElementType::Array, RawBsonRef::as_array)
319    }
320
321    /// Gets a reference to the BSON binary value corresponding to a given key or returns an error
322    /// if the key corresponds to a value which isn't a binary value.
323    ///
324    /// ```
325    /// use bson::{
326    ///     rawdoc,
327    ///     raw::ValueAccessErrorKind,
328    ///     spec::BinarySubtype,
329    ///     Binary,
330    /// };
331    ///
332    /// let doc = rawdoc! {
333    ///     "binary": Binary { subtype: BinarySubtype::Generic, bytes: vec![1, 2, 3] },
334    ///     "bool": true,
335    /// };
336    ///
337    /// assert_eq!(&doc.get_binary("binary")?.bytes, &[1, 2, 3]);
338    /// assert!(matches!(doc.get_binary("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. }));
339    /// assert!(matches!(doc.get_binary("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
340    /// # Ok::<(), Box<dyn std::error::Error>>(())
341    /// ```
342    pub fn get_binary(&self, key: impl AsRef<str>) -> ValueAccessResult<RawBinaryRef<'_>> {
343        self.get_with(key, ElementType::Binary, RawBsonRef::as_binary)
344    }
345
346    /// Gets a reference to the ObjectId value corresponding to a given key or returns an error if
347    /// the key corresponds to a value which isn't an ObjectId.
348    ///
349    /// ```
350    /// # use bson::raw::Error;
351    /// use bson::{rawdoc, oid::ObjectId, raw::ValueAccessErrorKind};
352    ///
353    /// let doc = rawdoc! {
354    ///     "_id": ObjectId::new(),
355    ///     "bool": true,
356    /// };
357    ///
358    /// let oid = doc.get_object_id("_id")?;
359    /// assert!(matches!(doc.get_object_id("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. }));
360    /// assert!(matches!(doc.get_object_id("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
361    /// # Ok::<(), Box<dyn std::error::Error>>(())
362    /// ```
363    pub fn get_object_id(&self, key: impl AsRef<str>) -> ValueAccessResult<ObjectId> {
364        self.get_with(key, ElementType::ObjectId, RawBsonRef::as_object_id)
365    }
366
367    /// Gets a reference to the boolean value corresponding to a given key or returns an error if
368    /// the key corresponds to a value which isn't a boolean.
369    ///
370    /// ```
371    /// # use bson::raw::Error;
372    /// use bson::{rawdoc, oid::ObjectId, raw::ValueAccessErrorKind};
373    ///
374    /// let doc = rawdoc! {
375    ///     "_id": ObjectId::new(),
376    ///     "bool": true,
377    /// };
378    ///
379    /// assert!(doc.get_bool("bool")?);
380    /// assert!(matches!(doc.get_bool("_id").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. }));
381    /// assert!(matches!(doc.get_bool("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
382    /// # Ok::<(), Box<dyn std::error::Error>>(())
383    /// ```
384    pub fn get_bool(&self, key: impl AsRef<str>) -> ValueAccessResult<bool> {
385        self.get_with(key, ElementType::Boolean, RawBsonRef::as_bool)
386    }
387
388    /// Gets a reference to the BSON DateTime value corresponding to a given key or returns an
389    /// error if the key corresponds to a value which isn't a DateTime.
390    ///
391    /// ```
392    /// # use bson::raw::Error;
393    /// use bson::{rawdoc, raw::ValueAccessErrorKind, DateTime};
394    ///
395    /// let dt = DateTime::now();
396    /// let doc = rawdoc! {
397    ///     "created_at": dt,
398    ///     "bool": true,
399    /// };
400    ///
401    /// assert_eq!(doc.get_datetime("created_at")?, dt);
402    /// assert!(matches!(doc.get_datetime("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. }));
403    /// assert!(matches!(doc.get_datetime("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
404    /// # Ok::<(), Box<dyn std::error::Error>>(())
405    /// ```
406    pub fn get_datetime(&self, key: impl AsRef<str>) -> ValueAccessResult<DateTime> {
407        self.get_with(key, ElementType::DateTime, RawBsonRef::as_datetime)
408    }
409
410    /// Gets a reference to the BSON regex value corresponding to a given key or returns an error if
411    /// the key corresponds to a value which isn't a regex.
412    ///
413    /// ```
414    /// use bson::{rawdoc, Regex, raw::ValueAccessErrorKind};
415    ///
416    /// let doc = rawdoc! {
417    ///     "regex": Regex {
418    ///         pattern: r"end\s*$".into(),
419    ///         options: "i".into(),
420    ///     },
421    ///     "bool": true,
422    /// };
423    ///
424    /// assert_eq!(doc.get_regex("regex")?.pattern, r"end\s*$");
425    /// assert_eq!(doc.get_regex("regex")?.options, "i");
426    /// assert!(matches!(doc.get_regex("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. }));
427    /// assert!(matches!(doc.get_regex("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
428    /// # Ok::<(), Box<dyn std::error::Error>>(())
429    /// ```
430    pub fn get_regex(&self, key: impl AsRef<str>) -> ValueAccessResult<RawRegexRef<'_>> {
431        self.get_with(key, ElementType::RegularExpression, RawBsonRef::as_regex)
432    }
433
434    /// Gets a reference to the BSON timestamp value corresponding to a given key or returns an
435    /// error if the key corresponds to a value which isn't a timestamp.
436    ///
437    /// ```
438    /// # use bson::raw::Error;
439    /// use bson::{rawdoc, Timestamp, raw::ValueAccessErrorKind};
440    ///
441    /// let doc = rawdoc! {
442    ///     "bool": true,
443    ///     "ts": Timestamp { time: 649876543, increment: 9 },
444    /// };
445    ///
446    /// let timestamp = doc.get_timestamp("ts")?;
447    ///
448    /// assert_eq!(timestamp.time, 649876543);
449    /// assert_eq!(timestamp.increment, 9);
450    /// assert!(matches!(doc.get_timestamp("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. }));
451    /// assert!(matches!(doc.get_timestamp("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
452    /// # Ok::<(), Box<dyn std::error::Error>>(())
453    /// ```
454    pub fn get_timestamp(&self, key: impl AsRef<str>) -> ValueAccessResult<Timestamp> {
455        self.get_with(key, ElementType::Timestamp, RawBsonRef::as_timestamp)
456    }
457
458    /// Gets a reference to the BSON int32 value corresponding to a given key or returns an error if
459    /// the key corresponds to a value which isn't a 32-bit integer.
460    ///
461    /// ```
462    /// # use bson::raw::Error;
463    /// use bson::{rawdoc, raw::ValueAccessErrorKind};
464    ///
465    /// let doc = rawdoc! {
466    ///     "bool": true,
467    ///     "i32": 1_000_000,
468    /// };
469    ///
470    /// assert_eq!(doc.get_i32("i32")?, 1_000_000);
471    /// assert!(matches!(doc.get_i32("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { ..}));
472    /// assert!(matches!(doc.get_i32("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
473    /// # Ok::<(), Box<dyn std::error::Error>>(())
474    /// ```
475    pub fn get_i32(&self, key: impl AsRef<str>) -> ValueAccessResult<i32> {
476        self.get_with(key, ElementType::Int32, RawBsonRef::as_i32)
477    }
478
479    /// Gets a reference to the BSON int64 value corresponding to a given key or returns an error if
480    /// the key corresponds to a value which isn't a 64-bit integer.
481    ///
482    /// ```
483    /// # use bson::raw::Error;
484    /// use bson::{rawdoc, raw::ValueAccessErrorKind};
485    ///
486    /// let doc = rawdoc! {
487    ///     "bool": true,
488    ///     "i64": 9223372036854775807_i64,
489    /// };
490    ///
491    /// assert_eq!(doc.get_i64("i64")?, 9223372036854775807);
492    /// assert!(matches!(doc.get_i64("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. }));
493    /// assert!(matches!(doc.get_i64("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent));
494    /// # Ok::<(), Box<dyn std::error::Error>>(())
495    /// ```
496    pub fn get_i64(&self, key: impl AsRef<str>) -> ValueAccessResult<i64> {
497        self.get_with(key, ElementType::Int64, RawBsonRef::as_i64)
498    }
499
500    /// Return a reference to the contained data as a `&[u8]`
501    ///
502    /// ```
503    /// # use bson::raw::Error;
504    /// use bson::rawdoc;
505    /// let docbuf = rawdoc! {};
506    /// assert_eq!(docbuf.as_bytes(), b"\x05\x00\x00\x00\x00");
507    /// # Ok::<(), Error>(())
508    /// ```
509    pub fn as_bytes(&self) -> &[u8] {
510        &self.data
511    }
512
513    /// Returns whether this document contains any elements or not.
514    pub fn is_empty(&self) -> bool {
515        self.as_bytes().len() == MIN_BSON_DOCUMENT_SIZE as usize
516    }
517
518    pub(crate) fn cstring_bytes_at(&self, start_at: usize) -> Result<&[u8]> {
519        let buf = &self.as_bytes()[start_at..];
520
521        let mut splits = buf.splitn(2, |x| *x == 0);
522        let value = splits.next().ok_or_else(|| Error::malformed("no value"))?;
523        if splits.next().is_some() {
524            Ok(value)
525        } else {
526            Err(Error::malformed("expected null terminator"))
527        }
528    }
529
530    pub(crate) fn read_cstring_at(&self, start_at: usize) -> Result<&str> {
531        let bytes = self.cstring_bytes_at(start_at)?;
532        try_to_str(bytes)
533    }
534}
535
536impl<'de: 'a, 'a> Deserialize<'de> for &'a RawDocument {
537    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
538    where
539        D: serde::Deserializer<'de>,
540    {
541        match OwnedOrBorrowedRawDocument::deserialize(deserializer)? {
542            OwnedOrBorrowedRawDocument::Borrowed(b) => Ok(b),
543            OwnedOrBorrowedRawDocument::Owned(d) => Err(serde::de::Error::custom(format!(
544                "expected borrowed raw document, instead got owned {:?}",
545                d
546            ))),
547        }
548    }
549}
550
551impl Serialize for &RawDocument {
552    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
553    where
554        S: serde::Serializer,
555    {
556        struct KvpSerializer<'a>(&'a RawDocument);
557
558        impl Serialize for KvpSerializer<'_> {
559            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
560            where
561                S: serde::Serializer,
562            {
563                if serializer.is_human_readable() {
564                    let mut map = serializer.serialize_map(None)?;
565                    for kvp in self.0 {
566                        let (k, v) = kvp.map_err(serde::ser::Error::custom)?;
567                        map.serialize_entry(k, &v)?;
568                    }
569                    map.end()
570                } else {
571                    serializer.serialize_bytes(self.0.as_bytes())
572                }
573            }
574        }
575        serializer.serialize_newtype_struct(RAW_DOCUMENT_NEWTYPE, &KvpSerializer(self))
576    }
577}
578
579impl std::fmt::Debug for RawDocument {
580    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
581        f.debug_struct("RawDocument")
582            .field("data", &hex::encode(&self.data))
583            .finish()
584    }
585}
586
587impl AsRef<RawDocument> for RawDocument {
588    fn as_ref(&self) -> &RawDocument {
589        self
590    }
591}
592
593impl ToOwned for RawDocument {
594    type Owned = RawDocumentBuf;
595
596    fn to_owned(&self) -> Self::Owned {
597        self.to_raw_document_buf()
598    }
599}
600
601impl<'a> From<&'a RawDocument> for Cow<'a, RawDocument> {
602    fn from(rdr: &'a RawDocument) -> Self {
603        Cow::Borrowed(rdr)
604    }
605}
606
607impl TryFrom<&RawDocument> for crate::Document {
608    type Error = Error;
609
610    fn try_from(rawdoc: &RawDocument) -> Result<Document> {
611        rawdoc
612            .into_iter()
613            .map(|res| res.and_then(|(k, v)| Ok((k.to_owned(), v.try_into()?))))
614            .collect()
615    }
616}
617
618impl<'a> IntoIterator for &'a RawDocument {
619    type IntoIter = Iter<'a>;
620    type Item = Result<(&'a str, RawBsonRef<'a>)>;
621
622    fn into_iter(self) -> Iter<'a> {
623        self.iter()
624    }
625}