bson/raw/
array_buf.rs

1use std::{
2    borrow::{Borrow, Cow},
3    fmt::Debug,
4    iter::FromIterator,
5};
6
7use serde::{Deserialize, Serialize};
8
9use crate::{RawArray, RawBsonRef, RawDocumentBuf};
10
11use super::{bson::RawBson, serde::OwnedOrBorrowedRawArray, RawArrayIter};
12
13/// An owned BSON array value (akin to [`std::path::PathBuf`]), backed by a buffer of raw BSON
14/// bytes. This type can be used to construct owned array values, which can be used to append to
15/// [`RawDocumentBuf`] or as a field in a [`Deserialize`] struct.
16///
17/// Iterating over a [`RawArrayBuf`] yields either an error or a [`RawBson`] value that borrows from
18/// the original document without making any additional allocations.
19/// ```
20/// # use bson::raw::Error;
21/// use bson::raw::RawArrayBuf;
22///
23/// let mut array = RawArrayBuf::new();
24/// array.push("a string");
25/// array.push(12_i32);
26///
27/// let mut iter = array.into_iter();
28///
29/// let value = iter.next().unwrap()?;
30/// assert_eq!(value.as_str(), Some("a string"));
31///
32/// let value = iter.next().unwrap()?;
33/// assert_eq!(value.as_i32(), Some(12));
34///
35/// assert!(iter.next().is_none());
36/// # Ok::<(), Error>(())
37/// ```
38///
39/// This type implements [`Deref`](std::ops::Deref) to [`RawArray`], meaning that all methods on
40/// [`RawArray`] are available on [`RawArrayBuf`] values as well. This includes [`RawArray::get`] or
41/// any of the type-specific getters, such as [`RawArray::get_object_id`] or [`RawArray::get_str`].
42/// Note that accessing elements is an O(N) operation, as it requires iterating through the document
43/// from the beginning to find the requested key.
44#[derive(Clone, PartialEq)]
45pub struct RawArrayBuf {
46    inner: RawDocumentBuf,
47    len: usize,
48}
49
50impl RawArrayBuf {
51    /// Construct a new, empty [`RawArrayBuf`].
52    pub fn new() -> RawArrayBuf {
53        Self {
54            inner: RawDocumentBuf::new(),
55            len: 0,
56        }
57    }
58
59    /// Construct a new [`RawArrayBuf`] from the provided [`Vec`] of bytes.
60    ///
61    /// This involves a traversal of the array to count the values.
62    pub(crate) fn from_raw_document_buf(doc: RawDocumentBuf) -> Self {
63        let len = doc.iter().count();
64        Self { inner: doc, len }
65    }
66
67    /// Append a value to the end of the array.
68    ///
69    /// ```
70    /// # use bson::raw::Error;
71    /// use bson::raw::{RawArrayBuf, RawDocumentBuf};
72    ///
73    /// let mut array = RawArrayBuf::new();
74    /// array.push("a string");
75    /// array.push(12_i32);
76    ///
77    /// let mut doc = RawDocumentBuf::new();
78    /// doc.append("a key", "a value");
79    /// array.push(doc.clone());
80    ///
81    /// let mut iter = array.into_iter();
82    ///
83    /// let value = iter.next().unwrap()?;
84    /// assert_eq!(value.as_str(), Some("a string"));
85    ///
86    /// let value = iter.next().unwrap()?;
87    /// assert_eq!(value.as_i32(), Some(12));
88    ///
89    /// let value = iter.next().unwrap()?;
90    /// assert_eq!(value.as_document(), Some(doc.as_ref()));
91    ///
92    /// assert!(iter.next().is_none());
93    /// # Ok::<(), Error>(())
94    /// ```
95    pub fn push(&mut self, value: impl Into<RawBson>) {
96        self.inner.append(self.len.to_string(), value);
97        self.len += 1;
98    }
99}
100
101impl Debug for RawArrayBuf {
102    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103        f.debug_struct("RawArrayBuf")
104            .field("data", &hex::encode(self.as_bytes()))
105            .field("len", &self.len)
106            .finish()
107    }
108}
109
110impl std::ops::Deref for RawArrayBuf {
111    type Target = RawArray;
112
113    fn deref(&self) -> &Self::Target {
114        RawArray::from_doc(&self.inner)
115    }
116}
117
118impl AsRef<RawArray> for RawArrayBuf {
119    fn as_ref(&self) -> &RawArray {
120        RawArray::from_doc(&self.inner)
121    }
122}
123
124impl Borrow<RawArray> for RawArrayBuf {
125    fn borrow(&self) -> &RawArray {
126        self.as_ref()
127    }
128}
129
130impl<'a> IntoIterator for &'a RawArrayBuf {
131    type IntoIter = RawArrayIter<'a>;
132    type Item = super::Result<RawBsonRef<'a>>;
133
134    fn into_iter(self) -> RawArrayIter<'a> {
135        self.as_ref().into_iter()
136    }
137}
138
139impl From<RawArrayBuf> for Cow<'_, RawArray> {
140    fn from(rd: RawArrayBuf) -> Self {
141        Cow::Owned(rd)
142    }
143}
144
145impl<'a> From<&'a RawArrayBuf> for Cow<'a, RawArray> {
146    fn from(rd: &'a RawArrayBuf) -> Self {
147        Cow::Borrowed(rd.as_ref())
148    }
149}
150
151impl<T: Into<RawBson>> FromIterator<T> for RawArrayBuf {
152    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
153        let mut array_buf = RawArrayBuf::new();
154        for item in iter {
155            array_buf.push(item);
156        }
157        array_buf
158    }
159}
160
161impl<'de> Deserialize<'de> for RawArrayBuf {
162    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
163    where
164        D: serde::Deserializer<'de>,
165    {
166        Ok(OwnedOrBorrowedRawArray::deserialize(deserializer)?.into_owned())
167    }
168}
169
170impl Serialize for RawArrayBuf {
171    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
172    where
173        S: serde::Serializer,
174    {
175        self.as_ref().serialize(serializer)
176    }
177}
178
179impl Default for RawArrayBuf {
180    fn default() -> Self {
181        Self::new()
182    }
183}