1use std::convert::TryFrom;
2
3use serde::{ser::SerializeSeq, Deserialize, Serialize};
4
5use super::{
6 error::{ValueAccessError, ValueAccessErrorKind, ValueAccessResult},
7 Error,
8 Iter,
9 RawBinary,
10 RawBson,
11 RawDocument,
12 RawRegex,
13 Result,
14};
15use crate::{
16 oid::ObjectId,
17 raw::{RawBsonVisitor, RAW_ARRAY_NEWTYPE},
18 spec::{BinarySubtype, ElementType},
19 Bson,
20 DateTime,
21 Timestamp,
22};
23
24#[derive(PartialEq)]
74#[repr(transparent)]
75pub struct RawArray {
76 pub(crate) doc: RawDocument,
77}
78
79impl RawArray {
80 pub(crate) fn from_doc(doc: &RawDocument) -> &RawArray {
81 unsafe { &*(doc as *const RawDocument as *const RawArray) }
91 }
92
93 pub fn get(&self, index: usize) -> Result<Option<RawBson<'_>>> {
95 self.into_iter().nth(index).transpose()
96 }
97
98 fn get_with<'a, T>(
99 &'a self,
100 index: usize,
101 expected_type: ElementType,
102 f: impl FnOnce(RawBson<'a>) -> Option<T>,
103 ) -> ValueAccessResult<T> {
104 let bson = self
105 .get(index)
106 .map_err(|e| ValueAccessError {
107 key: index.to_string(),
108 kind: ValueAccessErrorKind::InvalidBson(e),
109 })?
110 .ok_or(ValueAccessError {
111 key: index.to_string(),
112 kind: ValueAccessErrorKind::NotPresent,
113 })?;
114 match f(bson) {
115 Some(t) => Ok(t),
116 None => Err(ValueAccessError {
117 key: index.to_string(),
118 kind: ValueAccessErrorKind::UnexpectedType {
119 expected: expected_type,
120 actual: bson.element_type(),
121 },
122 }),
123 }
124 }
125
126 pub fn get_f64(&self, index: usize) -> ValueAccessResult<f64> {
129 self.get_with(index, ElementType::Double, RawBson::as_f64)
130 }
131
132 pub fn get_str(&self, index: usize) -> ValueAccessResult<&str> {
135 self.get_with(index, ElementType::String, RawBson::as_str)
136 }
137
138 pub fn get_document(&self, index: usize) -> ValueAccessResult<&RawDocument> {
141 self.get_with(index, ElementType::EmbeddedDocument, RawBson::as_document)
142 }
143
144 pub fn get_array(&self, index: usize) -> ValueAccessResult<&RawArray> {
147 self.get_with(index, ElementType::Array, RawBson::as_array)
148 }
149
150 pub fn get_binary(&self, index: usize) -> ValueAccessResult<RawBinary<'_>> {
153 self.get_with(index, ElementType::Binary, RawBson::as_binary)
154 }
155
156 pub fn get_object_id(&self, index: usize) -> ValueAccessResult<ObjectId> {
159 self.get_with(index, ElementType::ObjectId, RawBson::as_object_id)
160 }
161
162 pub fn get_bool(&self, index: usize) -> ValueAccessResult<bool> {
165 self.get_with(index, ElementType::Boolean, RawBson::as_bool)
166 }
167
168 pub fn get_datetime(&self, index: usize) -> ValueAccessResult<DateTime> {
171 self.get_with(index, ElementType::DateTime, RawBson::as_datetime)
172 }
173
174 pub fn get_regex(&self, index: usize) -> ValueAccessResult<RawRegex<'_>> {
177 self.get_with(index, ElementType::RegularExpression, RawBson::as_regex)
178 }
179
180 pub fn get_timestamp(&self, index: usize) -> ValueAccessResult<Timestamp> {
183 self.get_with(index, ElementType::Timestamp, RawBson::as_timestamp)
184 }
185
186 pub fn get_i32(&self, index: usize) -> ValueAccessResult<i32> {
189 self.get_with(index, ElementType::Int32, RawBson::as_i32)
190 }
191
192 pub fn get_i64(&self, index: usize) -> ValueAccessResult<i64> {
195 self.get_with(index, ElementType::Int64, RawBson::as_i64)
196 }
197
198 pub fn as_bytes(&self) -> &[u8] {
200 self.doc.as_bytes()
201 }
202}
203
204impl std::fmt::Debug for RawArray {
205 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
206 f.debug_struct("RawArray")
207 .field("data", &hex::encode(self.doc.as_bytes()))
208 .finish()
209 }
210}
211
212impl TryFrom<&RawArray> for Vec<Bson> {
213 type Error = Error;
214
215 fn try_from(arr: &RawArray) -> Result<Vec<Bson>> {
216 arr.into_iter()
217 .map(|result| {
218 let rawbson = result?;
219 Bson::try_from(rawbson)
220 })
221 .collect()
222 }
223}
224
225impl<'a> IntoIterator for &'a RawArray {
226 type IntoIter = RawArrayIter<'a>;
227 type Item = Result<RawBson<'a>>;
228
229 fn into_iter(self) -> RawArrayIter<'a> {
230 RawArrayIter {
231 inner: self.doc.into_iter(),
232 }
233 }
234}
235
236pub struct RawArrayIter<'a> {
238 inner: Iter<'a>,
239}
240
241impl<'a> Iterator for RawArrayIter<'a> {
242 type Item = Result<RawBson<'a>>;
243
244 fn next(&mut self) -> Option<Result<RawBson<'a>>> {
245 match self.inner.next() {
246 Some(Ok((_, v))) => Some(Ok(v)),
247 Some(Err(e)) => Some(Err(e)),
248 None => None,
249 }
250 }
251}
252
253impl<'de: 'a, 'a> Deserialize<'de> for &'a RawArray {
254 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
255 where
256 D: serde::Deserializer<'de>,
257 {
258 match deserializer.deserialize_newtype_struct(RAW_ARRAY_NEWTYPE, RawBsonVisitor)? {
259 RawBson::Array(d) => Ok(d),
260 RawBson::Binary(b) if b.subtype == BinarySubtype::Generic => {
261 let doc = RawDocument::new(b.bytes).map_err(serde::de::Error::custom)?;
262 Ok(RawArray::from_doc(doc))
263 }
264 b => Err(serde::de::Error::custom(format!(
265 "expected raw array reference, instead got {:?}",
266 b
267 ))),
268 }
269 }
270}
271
272impl<'a> Serialize for &'a RawArray {
273 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
274 where
275 S: serde::Serializer,
276 {
277 struct SeqSerializer<'a>(&'a RawArray);
278
279 impl<'a> Serialize for SeqSerializer<'a> {
280 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
281 where
282 S: serde::Serializer,
283 {
284 if serializer.is_human_readable() {
285 let mut seq = serializer.serialize_seq(None)?;
286 for v in self.0 {
287 let v = v.map_err(serde::ser::Error::custom)?;
288 seq.serialize_element(&v)?;
289 }
290 seq.end()
291 } else {
292 serializer.serialize_bytes(self.0.as_bytes())
293 }
294 }
295 }
296
297 serializer.serialize_newtype_struct(RAW_ARRAY_NEWTYPE, &SeqSerializer(self))
298 }
299}