1use std::convert::{TryFrom, TryInto};
2
3use serde::{ser::SerializeStruct, Deserialize, Serialize};
4use serde_bytes::Bytes;
5
6use super::{
7 bson::RawBson,
8 serde::{bson_visitor::OwnedOrBorrowedRawBsonVisitor, OwnedOrBorrowedRawBson},
9 Error,
10 RawArray,
11 RawDocument,
12 Result,
13};
14use crate::{
15 base64,
16 extjson,
17 oid::{self, ObjectId},
18 raw::{RawJavaScriptCodeWithScope, RAW_BSON_NEWTYPE},
19 spec::{BinarySubtype, ElementType},
20 Binary,
21 Bson,
22 DbPointer,
23 Decimal128,
24 RawArrayBuf,
25 RawDocumentBuf,
26 Regex,
27 Timestamp,
28};
29
30#[derive(Debug, Clone, Copy, PartialEq)]
32pub enum RawBsonRef<'a> {
33 Double(f64),
35 String(&'a str),
37 Array(&'a RawArray),
39 Document(&'a RawDocument),
41 Boolean(bool),
43 Null,
45 RegularExpression(RawRegexRef<'a>),
47 JavaScriptCode(&'a str),
49 JavaScriptCodeWithScope(RawJavaScriptCodeWithScopeRef<'a>),
51 Int32(i32),
53 Int64(i64),
55 Timestamp(Timestamp),
57 Binary(RawBinaryRef<'a>),
59 ObjectId(oid::ObjectId),
61 DateTime(crate::DateTime),
63 Symbol(&'a str),
65 Decimal128(Decimal128),
67 Undefined,
69 MaxKey,
71 MinKey,
73 DbPointer(RawDbPointerRef<'a>),
75}
76
77impl<'a> RawBsonRef<'a> {
78 pub fn element_type(&self) -> ElementType {
80 match *self {
81 RawBsonRef::Double(..) => ElementType::Double,
82 RawBsonRef::String(..) => ElementType::String,
83 RawBsonRef::Array(..) => ElementType::Array,
84 RawBsonRef::Document(..) => ElementType::EmbeddedDocument,
85 RawBsonRef::Boolean(..) => ElementType::Boolean,
86 RawBsonRef::Null => ElementType::Null,
87 RawBsonRef::RegularExpression(..) => ElementType::RegularExpression,
88 RawBsonRef::JavaScriptCode(..) => ElementType::JavaScriptCode,
89 RawBsonRef::JavaScriptCodeWithScope(..) => ElementType::JavaScriptCodeWithScope,
90 RawBsonRef::Int32(..) => ElementType::Int32,
91 RawBsonRef::Int64(..) => ElementType::Int64,
92 RawBsonRef::Timestamp(..) => ElementType::Timestamp,
93 RawBsonRef::Binary(..) => ElementType::Binary,
94 RawBsonRef::ObjectId(..) => ElementType::ObjectId,
95 RawBsonRef::DateTime(..) => ElementType::DateTime,
96 RawBsonRef::Symbol(..) => ElementType::Symbol,
97 RawBsonRef::Decimal128(..) => ElementType::Decimal128,
98 RawBsonRef::Undefined => ElementType::Undefined,
99 RawBsonRef::MaxKey => ElementType::MaxKey,
100 RawBsonRef::MinKey => ElementType::MinKey,
101 RawBsonRef::DbPointer(..) => ElementType::DbPointer,
102 }
103 }
104
105 pub fn as_f64(self) -> Option<f64> {
108 match self {
109 RawBsonRef::Double(d) => Some(d),
110 _ => None,
111 }
112 }
113
114 pub fn as_str(self) -> Option<&'a str> {
117 match self {
118 RawBsonRef::String(s) => Some(s),
119 _ => None,
120 }
121 }
122
123 pub fn as_array(self) -> Option<&'a RawArray> {
126 match self {
127 RawBsonRef::Array(v) => Some(v),
128 _ => None,
129 }
130 }
131
132 pub fn as_document(self) -> Option<&'a RawDocument> {
135 match self {
136 RawBsonRef::Document(v) => Some(v),
137 _ => None,
138 }
139 }
140
141 pub fn as_bool(self) -> Option<bool> {
144 match self {
145 RawBsonRef::Boolean(v) => Some(v),
146 _ => None,
147 }
148 }
149
150 pub fn as_i32(self) -> Option<i32> {
153 match self {
154 RawBsonRef::Int32(v) => Some(v),
155 _ => None,
156 }
157 }
158
159 pub fn as_i64(self) -> Option<i64> {
162 match self {
163 RawBsonRef::Int64(v) => Some(v),
164 _ => None,
165 }
166 }
167
168 pub fn as_object_id(self) -> Option<oid::ObjectId> {
171 match self {
172 RawBsonRef::ObjectId(v) => Some(v),
173 _ => None,
174 }
175 }
176
177 pub fn as_binary(self) -> Option<RawBinaryRef<'a>> {
180 match self {
181 RawBsonRef::Binary(v) => Some(v),
182 _ => None,
183 }
184 }
185
186 pub fn as_regex(self) -> Option<RawRegexRef<'a>> {
189 match self {
190 RawBsonRef::RegularExpression(v) => Some(v),
191 _ => None,
192 }
193 }
194
195 pub fn as_datetime(self) -> Option<crate::DateTime> {
198 match self {
199 RawBsonRef::DateTime(v) => Some(v),
200 _ => None,
201 }
202 }
203
204 pub fn as_symbol(self) -> Option<&'a str> {
207 match self {
208 RawBsonRef::Symbol(v) => Some(v),
209 _ => None,
210 }
211 }
212
213 pub fn as_timestamp(self) -> Option<Timestamp> {
216 match self {
217 RawBsonRef::Timestamp(timestamp) => Some(timestamp),
218 _ => None,
219 }
220 }
221
222 pub fn as_null(self) -> Option<()> {
225 match self {
226 RawBsonRef::Null => Some(()),
227 _ => None,
228 }
229 }
230
231 pub fn as_db_pointer(self) -> Option<RawDbPointerRef<'a>> {
234 match self {
235 RawBsonRef::DbPointer(d) => Some(d),
236 _ => None,
237 }
238 }
239
240 pub fn as_javascript(self) -> Option<&'a str> {
243 match self {
244 RawBsonRef::JavaScriptCode(s) => Some(s),
245 _ => None,
246 }
247 }
248
249 pub fn as_javascript_with_scope(self) -> Option<RawJavaScriptCodeWithScopeRef<'a>> {
252 match self {
253 RawBsonRef::JavaScriptCodeWithScope(s) => Some(s),
254 _ => None,
255 }
256 }
257
258 pub fn to_raw_bson(self) -> RawBson {
260 match self {
261 RawBsonRef::Double(d) => RawBson::Double(d),
262 RawBsonRef::String(s) => RawBson::String(s.to_string()),
263 RawBsonRef::Array(a) => RawBson::Array(a.to_owned()),
264 RawBsonRef::Document(d) => RawBson::Document(d.to_owned()),
265 RawBsonRef::Boolean(b) => RawBson::Boolean(b),
266 RawBsonRef::Null => RawBson::Null,
267 RawBsonRef::RegularExpression(re) => {
268 RawBson::RegularExpression(Regex::new(re.pattern, re.options))
269 }
270 RawBsonRef::JavaScriptCode(c) => RawBson::JavaScriptCode(c.to_owned()),
271 RawBsonRef::JavaScriptCodeWithScope(c_w_s) => {
272 RawBson::JavaScriptCodeWithScope(RawJavaScriptCodeWithScope {
273 code: c_w_s.code.to_string(),
274 scope: c_w_s.scope.to_owned(),
275 })
276 }
277 RawBsonRef::Int32(i) => RawBson::Int32(i),
278 RawBsonRef::Int64(i) => RawBson::Int64(i),
279 RawBsonRef::Timestamp(t) => RawBson::Timestamp(t),
280 RawBsonRef::Binary(b) => RawBson::Binary(Binary {
281 bytes: b.bytes.to_vec(),
282 subtype: b.subtype,
283 }),
284 RawBsonRef::ObjectId(o) => RawBson::ObjectId(o),
285 RawBsonRef::DateTime(dt) => RawBson::DateTime(dt),
286 RawBsonRef::Symbol(s) => RawBson::Symbol(s.to_string()),
287 RawBsonRef::Decimal128(d) => RawBson::Decimal128(d),
288 RawBsonRef::Undefined => RawBson::Undefined,
289 RawBsonRef::MaxKey => RawBson::MaxKey,
290 RawBsonRef::MinKey => RawBson::MinKey,
291 RawBsonRef::DbPointer(d) => RawBson::DbPointer(DbPointer {
292 namespace: d.namespace.to_string(),
293 id: d.id,
294 }),
295 }
296 }
297}
298
299impl<'de: 'a, 'a> Deserialize<'de> for RawBsonRef<'a> {
300 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
301 where
302 D: serde::Deserializer<'de>,
303 {
304 match deserializer
305 .deserialize_newtype_struct(RAW_BSON_NEWTYPE, OwnedOrBorrowedRawBsonVisitor)?
306 {
307 OwnedOrBorrowedRawBson::Borrowed(b) => Ok(b),
308 o => Err(serde::de::Error::custom(format!(
309 "RawBson must be deserialized from borrowed content, instead got {:?}",
310 o
311 ))),
312 }
313 }
314}
315
316impl Serialize for RawBsonRef<'_> {
317 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
318 where
319 S: serde::Serializer,
320 {
321 match self {
322 RawBsonRef::Double(v) => serializer.serialize_f64(*v),
323 RawBsonRef::String(v) => serializer.serialize_str(v),
324 RawBsonRef::Array(v) => v.serialize(serializer),
325 RawBsonRef::Document(v) => v.serialize(serializer),
326 RawBsonRef::Boolean(v) => serializer.serialize_bool(*v),
327 RawBsonRef::Null => serializer.serialize_unit(),
328 RawBsonRef::Int32(v) => serializer.serialize_i32(*v),
329 RawBsonRef::Int64(v) => serializer.serialize_i64(*v),
330 RawBsonRef::ObjectId(oid) => oid.serialize(serializer),
331 RawBsonRef::DateTime(dt) => dt.serialize(serializer),
332 RawBsonRef::Binary(b) => b.serialize(serializer),
333 RawBsonRef::JavaScriptCode(c) => {
334 let mut state = serializer.serialize_struct("$code", 1)?;
335 state.serialize_field("$code", c)?;
336 state.end()
337 }
338 RawBsonRef::JavaScriptCodeWithScope(code_w_scope) => code_w_scope.serialize(serializer),
339 RawBsonRef::DbPointer(dbp) => dbp.serialize(serializer),
340 RawBsonRef::Symbol(s) => {
341 let mut state = serializer.serialize_struct("$symbol", 1)?;
342 state.serialize_field("$symbol", s)?;
343 state.end()
344 }
345 RawBsonRef::RegularExpression(re) => re.serialize(serializer),
346 RawBsonRef::Timestamp(t) => t.serialize(serializer),
347 RawBsonRef::Decimal128(d) => d.serialize(serializer),
348 RawBsonRef::Undefined => {
349 let mut state = serializer.serialize_struct("$undefined", 1)?;
350 state.serialize_field("$undefined", &true)?;
351 state.end()
352 }
353 RawBsonRef::MaxKey => {
354 let mut state = serializer.serialize_struct("$maxKey", 1)?;
355 state.serialize_field("$maxKey", &1)?;
356 state.end()
357 }
358 RawBsonRef::MinKey => {
359 let mut state = serializer.serialize_struct("$minKey", 1)?;
360 state.serialize_field("$minKey", &1)?;
361 state.end()
362 }
363 }
364 }
365}
366
367impl<'a> TryFrom<RawBsonRef<'a>> for Bson {
368 type Error = Error;
369
370 fn try_from(rawbson: RawBsonRef<'a>) -> Result<Bson> {
371 rawbson.to_raw_bson().try_into()
372 }
373}
374
375impl From<i32> for RawBsonRef<'_> {
376 fn from(i: i32) -> Self {
377 RawBsonRef::Int32(i)
378 }
379}
380
381impl From<i64> for RawBsonRef<'_> {
382 fn from(i: i64) -> Self {
383 RawBsonRef::Int64(i)
384 }
385}
386
387impl<'a> From<&'a str> for RawBsonRef<'a> {
388 fn from(s: &'a str) -> Self {
389 RawBsonRef::String(s)
390 }
391}
392
393impl From<f64> for RawBsonRef<'_> {
394 fn from(f: f64) -> Self {
395 RawBsonRef::Double(f)
396 }
397}
398
399impl From<bool> for RawBsonRef<'_> {
400 fn from(b: bool) -> Self {
401 RawBsonRef::Boolean(b)
402 }
403}
404
405impl<'a> From<&'a RawDocumentBuf> for RawBsonRef<'a> {
406 fn from(d: &'a RawDocumentBuf) -> Self {
407 RawBsonRef::Document(d.as_ref())
408 }
409}
410
411impl<'a> From<&'a RawDocument> for RawBsonRef<'a> {
412 fn from(d: &'a RawDocument) -> Self {
413 RawBsonRef::Document(d)
414 }
415}
416
417impl<'a> From<&'a RawArray> for RawBsonRef<'a> {
418 fn from(a: &'a RawArray) -> Self {
419 RawBsonRef::Array(a)
420 }
421}
422
423impl<'a> From<&'a RawArrayBuf> for RawBsonRef<'a> {
424 fn from(a: &'a RawArrayBuf) -> Self {
425 RawBsonRef::Array(a)
426 }
427}
428
429impl From<crate::DateTime> for RawBsonRef<'_> {
430 fn from(dt: crate::DateTime) -> Self {
431 RawBsonRef::DateTime(dt)
432 }
433}
434
435impl From<Timestamp> for RawBsonRef<'_> {
436 fn from(ts: Timestamp) -> Self {
437 RawBsonRef::Timestamp(ts)
438 }
439}
440
441impl From<ObjectId> for RawBsonRef<'_> {
442 fn from(oid: ObjectId) -> Self {
443 RawBsonRef::ObjectId(oid)
444 }
445}
446
447impl From<Decimal128> for RawBsonRef<'_> {
448 fn from(d: Decimal128) -> Self {
449 RawBsonRef::Decimal128(d)
450 }
451}
452
453#[derive(Clone, Copy, Debug, PartialEq)]
455pub struct RawBinaryRef<'a> {
456 pub subtype: BinarySubtype,
458
459 pub bytes: &'a [u8],
461}
462
463impl RawBinaryRef<'_> {
464 pub fn to_binary(&self) -> Binary {
466 Binary {
467 subtype: self.subtype,
468 bytes: self.bytes.to_owned(),
469 }
470 }
471
472 pub(crate) fn len(&self) -> i32 {
473 match self.subtype {
474 BinarySubtype::BinaryOld => self.bytes.len() as i32 + 4,
475 _ => self.bytes.len() as i32,
476 }
477 }
478}
479
480impl<'de: 'a, 'a> Deserialize<'de> for RawBinaryRef<'a> {
481 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
482 where
483 D: serde::Deserializer<'de>,
484 {
485 match RawBsonRef::deserialize(deserializer)? {
486 RawBsonRef::Binary(b) => Ok(b),
487 c => Err(serde::de::Error::custom(format!(
488 "expected binary, but got {:?} instead",
489 c
490 ))),
491 }
492 }
493}
494
495impl Serialize for RawBinaryRef<'_> {
496 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
497 where
498 S: serde::Serializer,
499 {
500 if let BinarySubtype::Generic = self.subtype {
501 serializer.serialize_bytes(self.bytes)
502 } else if !serializer.is_human_readable() {
503 #[derive(Serialize)]
504 struct BorrowedBinary<'a> {
505 bytes: &'a Bytes,
506
507 #[serde(rename = "subType")]
508 subtype: u8,
509 }
510
511 let mut state = serializer.serialize_struct("$binary", 1)?;
512 let body = BorrowedBinary {
513 bytes: Bytes::new(self.bytes),
514 subtype: self.subtype.into(),
515 };
516 state.serialize_field("$binary", &body)?;
517 state.end()
518 } else {
519 let mut state = serializer.serialize_struct("$binary", 1)?;
520 let body = extjson::models::BinaryBody {
521 base64: base64::encode(self.bytes),
522 subtype: hex::encode([self.subtype.into()]),
523 };
524 state.serialize_field("$binary", &body)?;
525 state.end()
526 }
527 }
528}
529
530impl<'a> From<RawBinaryRef<'a>> for RawBsonRef<'a> {
531 fn from(b: RawBinaryRef<'a>) -> Self {
532 RawBsonRef::Binary(b)
533 }
534}
535
536impl<'a> From<&'a Binary> for RawBsonRef<'a> {
537 fn from(bin: &'a Binary) -> Self {
538 bin.as_raw_binary().into()
539 }
540}
541
542#[derive(Clone, Copy, Debug, PartialEq)]
544pub struct RawRegexRef<'a> {
545 pub pattern: &'a str,
547
548 pub options: &'a str,
556}
557
558impl<'de: 'a, 'a> Deserialize<'de> for RawRegexRef<'a> {
559 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
560 where
561 D: serde::Deserializer<'de>,
562 {
563 match RawBsonRef::deserialize(deserializer)? {
564 RawBsonRef::RegularExpression(b) => Ok(b),
565 c => Err(serde::de::Error::custom(format!(
566 "expected Regex, but got {:?} instead",
567 c
568 ))),
569 }
570 }
571}
572
573impl Serialize for RawRegexRef<'_> {
574 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
575 where
576 S: serde::Serializer,
577 {
578 #[derive(Serialize)]
579 struct BorrowedRegexBody<'a> {
580 pattern: &'a str,
581 options: &'a str,
582 }
583
584 let mut state = serializer.serialize_struct("$regularExpression", 1)?;
585 let body = BorrowedRegexBody {
586 pattern: self.pattern,
587 options: self.options,
588 };
589 state.serialize_field("$regularExpression", &body)?;
590 state.end()
591 }
592}
593
594impl<'a> From<RawRegexRef<'a>> for RawBsonRef<'a> {
595 fn from(re: RawRegexRef<'a>) -> Self {
596 RawBsonRef::RegularExpression(re)
597 }
598}
599
600#[derive(Clone, Copy, Debug, PartialEq)]
602pub struct RawJavaScriptCodeWithScopeRef<'a> {
603 pub code: &'a str,
605
606 pub scope: &'a RawDocument,
608}
609
610impl RawJavaScriptCodeWithScopeRef<'_> {
611 pub(crate) fn len(self) -> i32 {
612 4 + 4 + self.code.len() as i32 + 1 + self.scope.as_bytes().len() as i32
613 }
614}
615
616impl<'de: 'a, 'a> Deserialize<'de> for RawJavaScriptCodeWithScopeRef<'a> {
617 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
618 where
619 D: serde::Deserializer<'de>,
620 {
621 match RawBsonRef::deserialize(deserializer)? {
622 RawBsonRef::JavaScriptCodeWithScope(b) => Ok(b),
623 c => Err(serde::de::Error::custom(format!(
624 "expected CodeWithScope, but got {:?} instead",
625 c
626 ))),
627 }
628 }
629}
630
631impl Serialize for RawJavaScriptCodeWithScopeRef<'_> {
632 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
633 where
634 S: serde::Serializer,
635 {
636 let mut state = serializer.serialize_struct("$codeWithScope", 2)?;
637 state.serialize_field("$code", &self.code)?;
638 state.serialize_field("$scope", &self.scope)?;
639 state.end()
640 }
641}
642
643impl<'a> From<RawJavaScriptCodeWithScopeRef<'a>> for RawBsonRef<'a> {
644 fn from(code_w_scope: RawJavaScriptCodeWithScopeRef<'a>) -> Self {
645 RawBsonRef::JavaScriptCodeWithScope(code_w_scope)
646 }
647}
648
649#[derive(Debug, Clone, Copy, PartialEq)]
651pub struct RawDbPointerRef<'a> {
652 pub(crate) namespace: &'a str,
653 pub(crate) id: ObjectId,
654}
655
656impl<'de: 'a, 'a> Deserialize<'de> for RawDbPointerRef<'a> {
657 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
658 where
659 D: serde::Deserializer<'de>,
660 {
661 match RawBsonRef::deserialize(deserializer)? {
662 RawBsonRef::DbPointer(b) => Ok(b),
663 c => Err(serde::de::Error::custom(format!(
664 "expected DbPointer, but got {:?} instead",
665 c
666 ))),
667 }
668 }
669}
670
671impl Serialize for RawDbPointerRef<'_> {
672 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
673 where
674 S: serde::Serializer,
675 {
676 #[derive(Serialize)]
677 struct BorrowedDbPointerBody<'a> {
678 #[serde(rename = "$ref")]
679 ref_ns: &'a str,
680
681 #[serde(rename = "$id")]
682 id: ObjectId,
683 }
684
685 let mut state = serializer.serialize_struct("$dbPointer", 1)?;
686 let body = BorrowedDbPointerBody {
687 ref_ns: self.namespace,
688 id: self.id,
689 };
690 state.serialize_field("$dbPointer", &body)?;
691 state.end()
692 }
693}