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