1use std::convert::{TryFrom, TryInto};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 oid::{self, ObjectId},
7 raw::RAW_BSON_NEWTYPE,
8 spec::ElementType,
9 Binary,
10 Bson,
11 DbPointer,
12 Decimal128,
13 RawArray,
14 RawArrayBuf,
15 RawBinaryRef,
16 RawBsonRef,
17 RawDbPointerRef,
18 RawDocument,
19 RawDocumentBuf,
20 RawJavaScriptCodeWithScopeRef,
21 RawRegexRef,
22 Regex,
23 Timestamp,
24};
25
26use super::{
27 serde::{bson_visitor::OwnedOrBorrowedRawBsonVisitor, OwnedOrBorrowedRawBson},
28 Error,
29 Result,
30};
31
32#[derive(Debug, Clone, PartialEq)]
34pub enum RawBson {
35 Double(f64),
37 String(String),
39 Array(RawArrayBuf),
41 Document(RawDocumentBuf),
43 Boolean(bool),
45 Null,
47 RegularExpression(Regex),
49 JavaScriptCode(String),
51 JavaScriptCodeWithScope(RawJavaScriptCodeWithScope),
53 Int32(i32),
55 Int64(i64),
57 Timestamp(Timestamp),
59 Binary(Binary),
61 ObjectId(oid::ObjectId),
63 DateTime(crate::DateTime),
65 Symbol(String),
67 Decimal128(Decimal128),
69 Undefined,
71 MaxKey,
73 MinKey,
75 DbPointer(DbPointer),
77}
78
79impl RawBson {
80 pub fn element_type(&self) -> ElementType {
82 match *self {
83 RawBson::Double(..) => ElementType::Double,
84 RawBson::String(..) => ElementType::String,
85 RawBson::Array(..) => ElementType::Array,
86 RawBson::Document(..) => ElementType::EmbeddedDocument,
87 RawBson::Boolean(..) => ElementType::Boolean,
88 RawBson::Null => ElementType::Null,
89 RawBson::RegularExpression(..) => ElementType::RegularExpression,
90 RawBson::JavaScriptCode(..) => ElementType::JavaScriptCode,
91 RawBson::JavaScriptCodeWithScope(..) => ElementType::JavaScriptCodeWithScope,
92 RawBson::Int32(..) => ElementType::Int32,
93 RawBson::Int64(..) => ElementType::Int64,
94 RawBson::Timestamp(..) => ElementType::Timestamp,
95 RawBson::Binary(..) => ElementType::Binary,
96 RawBson::ObjectId(..) => ElementType::ObjectId,
97 RawBson::DateTime(..) => ElementType::DateTime,
98 RawBson::Symbol(..) => ElementType::Symbol,
99 RawBson::Decimal128(..) => ElementType::Decimal128,
100 RawBson::Undefined => ElementType::Undefined,
101 RawBson::MaxKey => ElementType::MaxKey,
102 RawBson::MinKey => ElementType::MinKey,
103 RawBson::DbPointer(..) => ElementType::DbPointer,
104 }
105 }
106
107 pub fn as_f64(&self) -> Option<f64> {
110 match self {
111 RawBson::Double(d) => Some(*d),
112 _ => None,
113 }
114 }
115
116 pub fn as_str(&self) -> Option<&'_ str> {
119 match self {
120 RawBson::String(s) => Some(s),
121 _ => None,
122 }
123 }
124
125 pub fn as_array(&self) -> Option<&'_ RawArray> {
128 match self {
129 RawBson::Array(v) => Some(v),
130 _ => None,
131 }
132 }
133
134 pub fn as_array_mut(&mut self) -> Option<&mut RawArrayBuf> {
137 match self {
138 RawBson::Array(ref mut v) => Some(v),
139 _ => None,
140 }
141 }
142
143 pub fn as_document(&self) -> Option<&'_ RawDocument> {
146 match self {
147 RawBson::Document(v) => Some(v),
148 _ => None,
149 }
150 }
151
152 pub fn as_document_mut(&mut self) -> Option<&mut RawDocumentBuf> {
155 match self {
156 RawBson::Document(ref mut v) => Some(v),
157 _ => None,
158 }
159 }
160
161 pub fn as_bool(&self) -> Option<bool> {
164 match self {
165 RawBson::Boolean(v) => Some(*v),
166 _ => None,
167 }
168 }
169
170 pub fn as_i32(&self) -> Option<i32> {
173 match self {
174 RawBson::Int32(v) => Some(*v),
175 _ => None,
176 }
177 }
178
179 pub fn as_i64(&self) -> Option<i64> {
182 match self {
183 RawBson::Int64(v) => Some(*v),
184 _ => None,
185 }
186 }
187
188 pub fn as_object_id(&self) -> Option<oid::ObjectId> {
191 match self {
192 RawBson::ObjectId(v) => Some(*v),
193 _ => None,
194 }
195 }
196
197 pub fn as_binary(&self) -> Option<RawBinaryRef<'_>> {
200 match self {
201 RawBson::Binary(v) => Some(RawBinaryRef {
202 bytes: v.bytes.as_slice(),
203 subtype: v.subtype,
204 }),
205 _ => None,
206 }
207 }
208
209 pub fn as_regex(&self) -> Option<RawRegexRef<'_>> {
212 match self {
213 RawBson::RegularExpression(v) => Some(RawRegexRef {
214 pattern: v.pattern.as_str(),
215 options: v.options.as_str(),
216 }),
217 _ => None,
218 }
219 }
220
221 pub fn as_datetime(&self) -> Option<crate::DateTime> {
224 match self {
225 RawBson::DateTime(v) => Some(*v),
226 _ => None,
227 }
228 }
229
230 pub fn as_symbol(&self) -> Option<&'_ str> {
233 match self {
234 RawBson::Symbol(v) => Some(v),
235 _ => None,
236 }
237 }
238
239 pub fn as_timestamp(&self) -> Option<Timestamp> {
242 match self {
243 RawBson::Timestamp(timestamp) => Some(*timestamp),
244 _ => None,
245 }
246 }
247
248 pub fn as_null(&self) -> Option<()> {
250 match self {
251 RawBson::Null => Some(()),
252 _ => None,
253 }
254 }
255
256 pub fn as_db_pointer(&self) -> Option<RawDbPointerRef<'_>> {
259 match self {
260 RawBson::DbPointer(d) => Some(RawDbPointerRef {
261 namespace: d.namespace.as_str(),
262 id: d.id,
263 }),
264 _ => None,
265 }
266 }
267
268 pub fn as_javascript(&self) -> Option<&'_ str> {
271 match self {
272 RawBson::JavaScriptCode(s) => Some(s),
273 _ => None,
274 }
275 }
276
277 pub fn as_javascript_with_scope(&self) -> Option<RawJavaScriptCodeWithScopeRef<'_>> {
280 match self {
281 RawBson::JavaScriptCodeWithScope(s) => Some(RawJavaScriptCodeWithScopeRef {
282 code: s.code.as_str(),
283 scope: &s.scope,
284 }),
285 _ => None,
286 }
287 }
288
289 pub fn as_raw_bson_ref(&self) -> RawBsonRef<'_> {
291 match self {
292 RawBson::Double(d) => RawBsonRef::Double(*d),
293 RawBson::String(s) => RawBsonRef::String(s.as_str()),
294 RawBson::Array(a) => RawBsonRef::Array(a),
295 RawBson::Document(d) => RawBsonRef::Document(d),
296 RawBson::Boolean(b) => RawBsonRef::Boolean(*b),
297 RawBson::Null => RawBsonRef::Null,
298 RawBson::RegularExpression(re) => RawBsonRef::RegularExpression(RawRegexRef {
299 options: re.options.as_str(),
300 pattern: re.pattern.as_str(),
301 }),
302 RawBson::JavaScriptCode(c) => RawBsonRef::JavaScriptCode(c.as_str()),
303 RawBson::JavaScriptCodeWithScope(code_w_scope) => {
304 RawBsonRef::JavaScriptCodeWithScope(RawJavaScriptCodeWithScopeRef {
305 code: code_w_scope.code.as_str(),
306 scope: code_w_scope.scope.as_ref(),
307 })
308 }
309 RawBson::Int32(i) => RawBsonRef::Int32(*i),
310 RawBson::Int64(i) => RawBsonRef::Int64(*i),
311 RawBson::Timestamp(ts) => RawBsonRef::Timestamp(*ts),
312 RawBson::Binary(b) => RawBsonRef::Binary(RawBinaryRef {
313 bytes: b.bytes.as_slice(),
314 subtype: b.subtype,
315 }),
316 RawBson::ObjectId(oid) => RawBsonRef::ObjectId(*oid),
317 RawBson::DateTime(dt) => RawBsonRef::DateTime(*dt),
318 RawBson::Symbol(s) => RawBsonRef::Symbol(s.as_str()),
319 RawBson::Decimal128(d) => RawBsonRef::Decimal128(*d),
320 RawBson::Undefined => RawBsonRef::Undefined,
321 RawBson::MaxKey => RawBsonRef::MaxKey,
322 RawBson::MinKey => RawBsonRef::MinKey,
323 RawBson::DbPointer(dbp) => RawBsonRef::DbPointer(RawDbPointerRef {
324 namespace: dbp.namespace.as_str(),
325 id: dbp.id,
326 }),
327 }
328 }
329}
330
331impl From<i32> for RawBson {
332 fn from(i: i32) -> Self {
333 RawBson::Int32(i)
334 }
335}
336
337impl From<i64> for RawBson {
338 fn from(i: i64) -> Self {
339 RawBson::Int64(i)
340 }
341}
342
343impl From<String> for RawBson {
344 fn from(s: String) -> Self {
345 RawBson::String(s)
346 }
347}
348
349impl From<&str> for RawBson {
350 fn from(s: &str) -> Self {
351 RawBson::String(s.to_owned())
352 }
353}
354
355impl From<f64> for RawBson {
356 fn from(f: f64) -> Self {
357 RawBson::Double(f)
358 }
359}
360
361impl From<bool> for RawBson {
362 fn from(b: bool) -> Self {
363 RawBson::Boolean(b)
364 }
365}
366
367impl From<RawDocumentBuf> for RawBson {
368 fn from(d: RawDocumentBuf) -> Self {
369 RawBson::Document(d)
370 }
371}
372
373impl From<RawArrayBuf> for RawBson {
374 fn from(a: RawArrayBuf) -> Self {
375 RawBson::Array(a)
376 }
377}
378
379impl From<crate::DateTime> for RawBson {
380 fn from(dt: crate::DateTime) -> Self {
381 RawBson::DateTime(dt)
382 }
383}
384
385impl From<Timestamp> for RawBson {
386 fn from(ts: Timestamp) -> Self {
387 RawBson::Timestamp(ts)
388 }
389}
390
391impl From<ObjectId> for RawBson {
392 fn from(oid: ObjectId) -> Self {
393 RawBson::ObjectId(oid)
394 }
395}
396
397impl From<Decimal128> for RawBson {
398 fn from(d: Decimal128) -> Self {
399 RawBson::Decimal128(d)
400 }
401}
402
403impl From<RawJavaScriptCodeWithScope> for RawBson {
404 fn from(code_w_scope: RawJavaScriptCodeWithScope) -> Self {
405 RawBson::JavaScriptCodeWithScope(code_w_scope)
406 }
407}
408
409impl From<Binary> for RawBson {
410 fn from(b: Binary) -> Self {
411 RawBson::Binary(b)
412 }
413}
414
415impl From<Regex> for RawBson {
416 fn from(re: Regex) -> Self {
417 RawBson::RegularExpression(re)
418 }
419}
420
421impl From<DbPointer> for RawBson {
422 fn from(d: DbPointer) -> Self {
423 RawBson::DbPointer(d)
424 }
425}
426
427impl<'de> Deserialize<'de> for RawBson {
428 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
429 where
430 D: serde::Deserializer<'de>,
431 {
432 match deserializer
433 .deserialize_newtype_struct(RAW_BSON_NEWTYPE, OwnedOrBorrowedRawBsonVisitor)?
434 {
435 OwnedOrBorrowedRawBson::Owned(o) => Ok(o),
436 OwnedOrBorrowedRawBson::Borrowed(b) => Ok(b.to_raw_bson()),
437 }
438 }
439}
440
441impl Serialize for RawBson {
442 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
443 where
444 S: serde::Serializer,
445 {
446 self.as_raw_bson_ref().serialize(serializer)
447 }
448}
449
450impl TryFrom<RawBson> for Bson {
451 type Error = Error;
452
453 fn try_from(rawbson: RawBson) -> Result<Bson> {
454 Ok(match rawbson {
455 RawBson::Double(d) => Bson::Double(d),
456 RawBson::String(s) => Bson::String(s),
457 RawBson::Document(rawdoc) => Bson::Document(rawdoc.as_ref().try_into()?),
458 RawBson::Array(rawarray) => Bson::Array(rawarray.as_ref().try_into()?),
459 RawBson::Binary(rawbson) => Bson::Binary(rawbson),
460 RawBson::ObjectId(rawbson) => Bson::ObjectId(rawbson),
461 RawBson::Boolean(rawbson) => Bson::Boolean(rawbson),
462 RawBson::DateTime(rawbson) => Bson::DateTime(rawbson),
463 RawBson::Null => Bson::Null,
464 RawBson::RegularExpression(rawregex) => Bson::RegularExpression(rawregex),
465 RawBson::JavaScriptCode(rawbson) => Bson::JavaScriptCode(rawbson),
466 RawBson::Int32(rawbson) => Bson::Int32(rawbson),
467 RawBson::Timestamp(rawbson) => Bson::Timestamp(rawbson),
468 RawBson::Int64(rawbson) => Bson::Int64(rawbson),
469 RawBson::Undefined => Bson::Undefined,
470 RawBson::DbPointer(rawbson) => Bson::DbPointer(rawbson),
471 RawBson::Symbol(rawbson) => Bson::Symbol(rawbson),
472 RawBson::JavaScriptCodeWithScope(rawbson) => {
473 Bson::JavaScriptCodeWithScope(crate::JavaScriptCodeWithScope {
474 code: rawbson.code,
475 scope: rawbson.scope.try_into()?,
476 })
477 }
478 RawBson::Decimal128(rawbson) => Bson::Decimal128(rawbson),
479 RawBson::MaxKey => Bson::MaxKey,
480 RawBson::MinKey => Bson::MinKey,
481 })
482 }
483}
484
485impl TryFrom<Bson> for RawBson {
486 type Error = Error;
487
488 fn try_from(bson: Bson) -> Result<RawBson> {
489 Ok(match bson {
490 Bson::Double(d) => RawBson::Double(d),
491 Bson::String(s) => RawBson::String(s),
492 Bson::Document(doc) => RawBson::Document((&doc).try_into()?),
493 Bson::Array(arr) => RawBson::Array(
494 arr.into_iter()
495 .map(|b| -> Result<RawBson> { b.try_into() })
496 .collect::<Result<RawArrayBuf>>()?,
497 ),
498 Bson::Binary(bin) => RawBson::Binary(bin),
499 Bson::ObjectId(id) => RawBson::ObjectId(id),
500 Bson::Boolean(b) => RawBson::Boolean(b),
501 Bson::DateTime(dt) => RawBson::DateTime(dt),
502 Bson::Null => RawBson::Null,
503 Bson::RegularExpression(regex) => RawBson::RegularExpression(regex),
504 Bson::JavaScriptCode(s) => RawBson::JavaScriptCode(s),
505 Bson::Int32(i) => RawBson::Int32(i),
506 Bson::Timestamp(ts) => RawBson::Timestamp(ts),
507 Bson::Int64(i) => RawBson::Int64(i),
508 Bson::Undefined => RawBson::Undefined,
509 Bson::DbPointer(p) => RawBson::DbPointer(p),
510 Bson::Symbol(s) => RawBson::Symbol(s),
511 Bson::JavaScriptCodeWithScope(jcws) => {
512 RawBson::JavaScriptCodeWithScope(crate::RawJavaScriptCodeWithScope {
513 code: jcws.code,
514 scope: (&jcws.scope).try_into()?,
515 })
516 }
517 Bson::Decimal128(d) => RawBson::Decimal128(d),
518 Bson::MaxKey => RawBson::MaxKey,
519 Bson::MinKey => RawBson::MinKey,
520 })
521 }
522}
523
524#[derive(Debug, Clone, PartialEq)]
526pub struct RawJavaScriptCodeWithScope {
527 pub code: String,
529
530 pub scope: RawDocumentBuf,
532}
533
534impl<'de> Deserialize<'de> for RawJavaScriptCodeWithScope {
535 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
536 where
537 D: serde::Deserializer<'de>,
538 {
539 match RawBson::deserialize(deserializer)? {
540 RawBson::JavaScriptCodeWithScope(b) => Ok(b),
541 c => Err(serde::de::Error::custom(format!(
542 "expected CodeWithScope, but got {:?} instead",
543 c
544 ))),
545 }
546 }
547}
548
549impl Serialize for RawJavaScriptCodeWithScope {
550 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
551 where
552 S: serde::Serializer,
553 {
554 let raw = RawJavaScriptCodeWithScopeRef {
555 code: self.code.as_str(),
556 scope: self.scope.as_ref(),
557 };
558
559 raw.serialize(serializer)
560 }
561}