1use std::{borrow::Cow, convert::TryFrom};
2
3use super::{
4 Error as RawError,
5 RawBinaryRef,
6 RawBsonRef,
7 RawDocument,
8 RawIter,
9 RawRegexRef,
10 Result as RawResult,
11};
12use crate::{
13 error::{Error, Result},
14 oid::ObjectId,
15 spec::ElementType,
16 Bson,
17 DateTime,
18 RawArrayBuf,
19 Timestamp,
20};
21
22#[derive(PartialEq)]
71#[repr(transparent)]
72pub struct RawArray {
73 pub(crate) doc: RawDocument,
74}
75
76impl RawArray {
77 pub(crate) fn from_doc(doc: &RawDocument) -> &RawArray {
78 unsafe { &*(doc as *const RawDocument as *const RawArray) }
88 }
89
90 #[cfg(feature = "serde")]
91 pub(crate) fn as_doc(&self) -> &RawDocument {
92 &self.doc
93 }
94
95 pub fn get(&self, index: usize) -> RawResult<Option<RawBsonRef<'_>>> {
97 self.into_iter().nth(index).transpose()
98 }
99
100 fn get_with<'a, T>(
101 &'a self,
102 index: usize,
103 expected_type: ElementType,
104 f: impl FnOnce(RawBsonRef<'a>) -> Option<T>,
105 ) -> Result<T> {
106 let bson = self
107 .get(index)
108 .map_err(|e| Error::value_access_invalid_bson(format!("{:?}", e)))?
109 .ok_or_else(Error::value_access_not_present)
110 .map_err(|e| e.with_index(index))?;
111 match f(bson) {
112 Some(t) => Ok(t),
113 None => Err(
114 Error::value_access_unexpected_type(bson.element_type(), expected_type)
115 .with_index(index),
116 ),
117 }
118 }
119
120 pub fn get_f64(&self, index: usize) -> Result<f64> {
123 self.get_with(index, ElementType::Double, RawBsonRef::as_f64)
124 }
125
126 pub fn get_str(&self, index: usize) -> Result<&str> {
129 self.get_with(index, ElementType::String, RawBsonRef::as_str)
130 }
131
132 pub fn get_document(&self, index: usize) -> Result<&RawDocument> {
135 self.get_with(
136 index,
137 ElementType::EmbeddedDocument,
138 RawBsonRef::as_document,
139 )
140 }
141
142 pub fn get_array(&self, index: usize) -> Result<&RawArray> {
145 self.get_with(index, ElementType::Array, RawBsonRef::as_array)
146 }
147
148 pub fn get_binary(&self, index: usize) -> Result<RawBinaryRef<'_>> {
151 self.get_with(index, ElementType::Binary, RawBsonRef::as_binary)
152 }
153
154 pub fn get_object_id(&self, index: usize) -> Result<ObjectId> {
157 self.get_with(index, ElementType::ObjectId, RawBsonRef::as_object_id)
158 }
159
160 pub fn get_bool(&self, index: usize) -> Result<bool> {
163 self.get_with(index, ElementType::Boolean, RawBsonRef::as_bool)
164 }
165
166 pub fn get_datetime(&self, index: usize) -> Result<DateTime> {
169 self.get_with(index, ElementType::DateTime, RawBsonRef::as_datetime)
170 }
171
172 pub fn get_regex(&self, index: usize) -> Result<RawRegexRef<'_>> {
175 self.get_with(index, ElementType::RegularExpression, RawBsonRef::as_regex)
176 }
177
178 pub fn get_timestamp(&self, index: usize) -> Result<Timestamp> {
181 self.get_with(index, ElementType::Timestamp, RawBsonRef::as_timestamp)
182 }
183
184 pub fn get_i32(&self, index: usize) -> Result<i32> {
187 self.get_with(index, ElementType::Int32, RawBsonRef::as_i32)
188 }
189
190 pub fn get_i64(&self, index: usize) -> Result<i64> {
193 self.get_with(index, ElementType::Int64, RawBsonRef::as_i64)
194 }
195
196 pub fn as_bytes(&self) -> &[u8] {
198 self.doc.as_bytes()
199 }
200
201 pub fn is_empty(&self) -> bool {
203 self.doc.is_empty()
204 }
205
206 pub fn iter_elements(&self) -> RawIter<'_> {
217 RawIter::new(&self.doc)
218 }
219}
220
221impl std::fmt::Debug for RawArray {
222 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223 f.debug_struct("RawArray")
224 .field("data", &hex::encode(self.doc.as_bytes()))
225 .finish()
226 }
227}
228
229impl TryFrom<&RawArray> for Vec<Bson> {
230 type Error = RawError;
231
232 fn try_from(arr: &RawArray) -> RawResult<Vec<Bson>> {
233 arr.into_iter()
234 .map(|result| {
235 let rawbson = result?;
236 Bson::try_from(rawbson)
237 })
238 .collect()
239 }
240}
241
242impl ToOwned for RawArray {
243 type Owned = RawArrayBuf;
244
245 fn to_owned(&self) -> Self::Owned {
246 RawArrayBuf::from_raw_document_buf(self.doc.to_owned())
247 }
248}
249
250impl<'a> From<&'a RawArray> for Cow<'a, RawArray> {
251 fn from(rdr: &'a RawArray) -> Self {
252 Cow::Borrowed(rdr)
253 }
254}
255
256impl<'a> IntoIterator for &'a RawArray {
257 type IntoIter = RawArrayIter<'a>;
258 type Item = RawResult<RawBsonRef<'a>>;
259
260 fn into_iter(self) -> RawArrayIter<'a> {
261 RawArrayIter {
262 inner: RawIter::new(&self.doc),
263 }
264 }
265}
266
267pub struct RawArrayIter<'a> {
269 inner: RawIter<'a>,
270}
271
272impl<'a> Iterator for RawArrayIter<'a> {
273 type Item = RawResult<RawBsonRef<'a>>;
274
275 fn next(&mut self) -> Option<RawResult<RawBsonRef<'a>>> {
276 match self.inner.next() {
277 Some(Ok(elem)) => match elem.value() {
278 Ok(value) => Some(Ok(value)),
279 Err(e) => Some(Err(e)),
280 },
281 Some(Err(e)) => Some(Err(e)),
282 None => None,
283 }
284 }
285}
286
287#[cfg(feature = "serde")]
288impl<'de: 'a, 'a> serde::Deserialize<'de> for &'a RawArray {
289 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
290 where
291 D: serde::Deserializer<'de>,
292 {
293 use super::serde::OwnedOrBorrowedRawArray;
294 match OwnedOrBorrowedRawArray::deserialize(deserializer)? {
295 OwnedOrBorrowedRawArray::Borrowed(b) => Ok(b),
296 o => Err(serde::de::Error::custom(format!(
297 "expected borrowed raw array, instead got owned {:?}",
298 o
299 ))),
300 }
301 }
302}
303
304#[cfg(feature = "serde")]
305impl serde::Serialize for &RawArray {
306 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
307 where
308 S: serde::Serializer,
309 {
310 struct SeqSerializer<'a>(&'a RawArray);
311
312 impl serde::Serialize for SeqSerializer<'_> {
313 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
314 where
315 S: serde::Serializer,
316 {
317 use serde::ser::SerializeSeq as _;
318 if serializer.is_human_readable() {
319 let mut seq = serializer.serialize_seq(None)?;
320 for v in self.0 {
321 let v = v.map_err(serde::ser::Error::custom)?;
322 seq.serialize_element(&v)?;
323 }
324 seq.end()
325 } else {
326 serializer.serialize_bytes(self.0.as_bytes())
327 }
328 }
329 }
330
331 serializer.serialize_newtype_struct(crate::raw::RAW_ARRAY_NEWTYPE, &SeqSerializer(self))
332 }
333}