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}