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}