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