[go: up one dir, main page]

bson/ser/
serde.rs

1use serde::ser::{
2    self,
3    Error as SerdeError,
4    Serialize,
5    SerializeMap,
6    SerializeSeq,
7    SerializeStruct,
8    SerializeStructVariant,
9    SerializeTuple,
10    SerializeTupleStruct,
11    SerializeTupleVariant,
12};
13
14use crate::{
15    base64,
16    bson::{Array, Bson, DbPointer, Document, JavaScriptCodeWithScope, Regex, Timestamp},
17    datetime::DateTime,
18    error::{Error, Result},
19    extjson,
20    oid::ObjectId,
21    raw::{RawDbPointerRef, RawRegexRef, RAW_ARRAY_NEWTYPE, RAW_DOCUMENT_NEWTYPE},
22    serde_helpers::HUMAN_READABLE_NEWTYPE,
23    spec::BinarySubtype,
24    uuid::UUID_NEWTYPE_NAME,
25    Binary,
26    Decimal128,
27};
28
29use super::to_bson_with_options;
30
31impl Serialize for ObjectId {
32    #[inline]
33    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
34    where
35        S: serde::ser::Serializer,
36    {
37        let mut ser = serializer.serialize_struct("$oid", 1)?;
38        ser.serialize_field("$oid", &self.to_string())?;
39        ser.end()
40    }
41}
42
43impl Serialize for Document {
44    #[inline]
45    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
46    where
47        S: ser::Serializer,
48    {
49        let mut state = serializer.serialize_map(Some(self.len()))?;
50        for (k, v) in self {
51            state.serialize_entry(k, v)?;
52        }
53        state.end()
54    }
55}
56
57impl Serialize for Bson {
58    #[inline]
59    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
60    where
61        S: ser::Serializer,
62    {
63        match self {
64            Bson::Double(v) => serializer.serialize_f64(*v),
65            Bson::String(v) => serializer.serialize_str(v),
66            Bson::Array(v) => v.serialize(serializer),
67            Bson::Document(v) => v.serialize(serializer),
68            Bson::Boolean(v) => serializer.serialize_bool(*v),
69            Bson::Null => serializer.serialize_unit(),
70            Bson::Int32(v) => serializer.serialize_i32(*v),
71            Bson::Int64(v) => serializer.serialize_i64(*v),
72            Bson::ObjectId(oid) => oid.serialize(serializer),
73            Bson::DateTime(dt) => dt.serialize(serializer),
74            Bson::Binary(b) => b.serialize(serializer),
75            Bson::JavaScriptCode(c) => {
76                let mut state = serializer.serialize_struct("$code", 1)?;
77                state.serialize_field("$code", c)?;
78                state.end()
79            }
80            Bson::JavaScriptCodeWithScope(code_w_scope) => code_w_scope.serialize(serializer),
81            Bson::DbPointer(dbp) => dbp.serialize(serializer),
82            Bson::Symbol(s) => {
83                let mut state = serializer.serialize_struct("$symbol", 1)?;
84                state.serialize_field("$symbol", s)?;
85                state.end()
86            }
87            Bson::RegularExpression(re) => re.serialize(serializer),
88            Bson::Timestamp(t) => t.serialize(serializer),
89            Bson::Decimal128(d) => d.serialize(serializer),
90            Bson::Undefined => {
91                let mut state = serializer.serialize_struct("$undefined", 1)?;
92                state.serialize_field("$undefined", &true)?;
93                state.end()
94            }
95            Bson::MaxKey => {
96                let mut state = serializer.serialize_struct("$maxKey", 1)?;
97                state.serialize_field("$maxKey", &1)?;
98                state.end()
99            }
100            Bson::MinKey => {
101                let mut state = serializer.serialize_struct("$minKey", 1)?;
102                state.serialize_field("$minKey", &1)?;
103                state.end()
104            }
105        }
106    }
107}
108
109/// Serde Serializer
110#[non_exhaustive]
111pub struct Serializer {
112    options: SerializerOptions,
113}
114
115/// Options used to configure a [`Serializer`].
116#[derive(Debug, Clone, Default)]
117#[non_exhaustive]
118pub(crate) struct SerializerOptions {
119    /// Whether the [`Serializer`] should present itself as human readable or not.
120    /// The default value is true. For internal use only.
121    pub(crate) human_readable: Option<bool>,
122}
123
124impl Serializer {
125    /// Construct a new [`Serializer`].
126    #[allow(clippy::new_without_default)]
127    pub fn new() -> Serializer {
128        Serializer {
129            options: Default::default(),
130        }
131    }
132
133    /// Construct a new [`Serializer`] configured with the provided [`SerializerOptions`].
134    pub(crate) fn new_with_options(options: SerializerOptions) -> Self {
135        Serializer { options }
136    }
137}
138
139impl ser::Serializer for Serializer {
140    type Ok = Bson;
141    type Error = Error;
142
143    type SerializeSeq = ArraySerializer;
144    type SerializeTuple = TupleSerializer;
145    type SerializeTupleStruct = TupleStructSerializer;
146    type SerializeTupleVariant = TupleVariantSerializer;
147    type SerializeMap = MapSerializer;
148    type SerializeStruct = StructSerializer;
149    type SerializeStructVariant = StructVariantSerializer;
150
151    #[inline]
152    fn serialize_bool(self, value: bool) -> crate::ser::Result<Bson> {
153        Ok(Bson::Boolean(value))
154    }
155
156    #[inline]
157    fn serialize_i8(self, value: i8) -> crate::ser::Result<Bson> {
158        self.serialize_i32(value as i32)
159    }
160
161    #[inline]
162    fn serialize_u8(self, value: u8) -> crate::ser::Result<Bson> {
163        Ok(Bson::Int32(value as i32))
164    }
165
166    #[inline]
167    fn serialize_i16(self, value: i16) -> crate::ser::Result<Bson> {
168        self.serialize_i32(value as i32)
169    }
170
171    #[inline]
172    fn serialize_u16(self, value: u16) -> crate::ser::Result<Bson> {
173        Ok(Bson::Int32(value as i32))
174    }
175
176    #[inline]
177    fn serialize_i32(self, value: i32) -> crate::ser::Result<Bson> {
178        Ok(Bson::Int32(value))
179    }
180
181    #[inline]
182    fn serialize_u32(self, value: u32) -> crate::ser::Result<Bson> {
183        Ok(Bson::Int64(value as i64))
184    }
185
186    #[inline]
187    fn serialize_i64(self, value: i64) -> crate::ser::Result<Bson> {
188        Ok(Bson::Int64(value))
189    }
190
191    #[inline]
192    fn serialize_u64(self, value: u64) -> crate::ser::Result<Bson> {
193        use std::convert::TryFrom;
194
195        match i64::try_from(value) {
196            Ok(ivalue) => Ok(Bson::Int64(ivalue)),
197            Err(_) => Err(Error::too_large_integer(value)),
198        }
199    }
200
201    #[inline]
202    fn serialize_f32(self, value: f32) -> crate::ser::Result<Bson> {
203        self.serialize_f64(value as f64)
204    }
205
206    #[inline]
207    fn serialize_f64(self, value: f64) -> crate::ser::Result<Bson> {
208        Ok(Bson::Double(value))
209    }
210
211    #[inline]
212    fn serialize_char(self, value: char) -> crate::ser::Result<Bson> {
213        let mut s = String::new();
214        s.push(value);
215        self.serialize_str(&s)
216    }
217
218    #[inline]
219    fn serialize_str(self, value: &str) -> crate::ser::Result<Bson> {
220        Ok(Bson::String(value.to_string()))
221    }
222
223    fn serialize_bytes(self, value: &[u8]) -> crate::ser::Result<Bson> {
224        // let mut state = self.serialize_seq(Some(value.len()))?;
225        // for byte in value {
226        //     state.serialize_element(byte)?;
227        // }
228        // state.end()
229        Ok(Bson::Binary(Binary {
230            subtype: BinarySubtype::Generic,
231            bytes: value.to_vec(),
232        }))
233    }
234
235    #[inline]
236    fn serialize_none(self) -> crate::ser::Result<Bson> {
237        self.serialize_unit()
238    }
239
240    #[inline]
241    fn serialize_some<V>(self, value: &V) -> crate::ser::Result<Bson>
242    where
243        V: Serialize + ?Sized,
244    {
245        value.serialize(self)
246    }
247
248    #[inline]
249    fn serialize_unit(self) -> crate::ser::Result<Bson> {
250        Ok(Bson::Null)
251    }
252
253    #[inline]
254    fn serialize_unit_struct(self, _name: &'static str) -> crate::ser::Result<Bson> {
255        self.serialize_unit()
256    }
257
258    #[inline]
259    fn serialize_unit_variant(
260        self,
261        _name: &'static str,
262        _variant_index: u32,
263        variant: &'static str,
264    ) -> crate::ser::Result<Bson> {
265        Ok(Bson::String(variant.to_string()))
266    }
267
268    #[inline]
269    fn serialize_newtype_struct<T>(
270        mut self,
271        name: &'static str,
272        value: &T,
273    ) -> crate::ser::Result<Bson>
274    where
275        T: Serialize + ?Sized,
276    {
277        match name {
278            UUID_NEWTYPE_NAME => {
279                let is_human_readable = self.is_human_readable();
280                match value.serialize(self)? {
281                    Bson::String(s) if is_human_readable => {
282                        // the serializer reports itself as human readable, so [`Uuid`] will
283                        // serialize itself as a string.
284                        let uuid = crate::Uuid::parse_str(s).map_err(Error::custom)?;
285                        Ok(Bson::Binary(uuid.into()))
286                    }
287                    Bson::Binary(b) if !is_human_readable => Ok(Bson::Binary(Binary {
288                        bytes: b.bytes,
289                        subtype: BinarySubtype::Uuid,
290                    })),
291                    b => {
292                        let expectation = if is_human_readable {
293                            "a string"
294                        } else {
295                            "bytes"
296                        };
297                        Err(Error::custom(format!(
298                            "expected UUID to be serialized as {} but got {:?} instead",
299                            expectation, b
300                        )))
301                    }
302                }
303            }
304            // when in non-human-readable mode, raw document / raw array will serialize as bytes.
305            RAW_DOCUMENT_NEWTYPE | RAW_ARRAY_NEWTYPE if !self.is_human_readable() => match value
306                .serialize(self)?
307            {
308                Bson::Binary(b) => {
309                    let doc = Document::from_reader(b.bytes.as_slice()).map_err(Error::custom)?;
310
311                    if name == RAW_DOCUMENT_NEWTYPE {
312                        Ok(Bson::Document(doc))
313                    } else {
314                        Ok(Bson::Array(doc.into_iter().map(|kvp| kvp.1).collect()))
315                    }
316                }
317                b => Err(Error::custom(format!(
318                    "expected raw document or array to be serialized as bytes but got {:?} instead",
319                    b
320                ))),
321            },
322            HUMAN_READABLE_NEWTYPE => {
323                self.options.human_readable = Some(true);
324                value.serialize(self)
325            }
326            _ => value.serialize(self),
327        }
328    }
329
330    #[inline]
331    fn serialize_newtype_variant<T>(
332        self,
333        _name: &'static str,
334        _variant_index: u32,
335        variant: &'static str,
336        value: &T,
337    ) -> crate::ser::Result<Bson>
338    where
339        T: Serialize + ?Sized,
340    {
341        let mut newtype_variant = Document::new();
342        newtype_variant.insert(variant, to_bson_with_options(value, self.options)?);
343        Ok(newtype_variant.into())
344    }
345
346    #[inline]
347    fn serialize_seq(self, len: Option<usize>) -> crate::ser::Result<Self::SerializeSeq> {
348        Ok(ArraySerializer {
349            inner: Array::with_capacity(len.unwrap_or(0)),
350            options: self.options,
351        })
352    }
353
354    #[inline]
355    fn serialize_tuple(self, len: usize) -> crate::ser::Result<Self::SerializeTuple> {
356        Ok(TupleSerializer {
357            inner: Array::with_capacity(len),
358            options: self.options,
359        })
360    }
361
362    #[inline]
363    fn serialize_tuple_struct(
364        self,
365        _name: &'static str,
366        len: usize,
367    ) -> crate::ser::Result<Self::SerializeTupleStruct> {
368        Ok(TupleStructSerializer {
369            inner: Array::with_capacity(len),
370            options: self.options,
371        })
372    }
373
374    #[inline]
375    fn serialize_tuple_variant(
376        self,
377        _name: &'static str,
378        _variant_index: u32,
379        variant: &'static str,
380        len: usize,
381    ) -> crate::ser::Result<Self::SerializeTupleVariant> {
382        Ok(TupleVariantSerializer {
383            inner: Array::with_capacity(len),
384            name: variant,
385            options: self.options,
386        })
387    }
388
389    #[inline]
390    fn serialize_map(self, _len: Option<usize>) -> crate::ser::Result<Self::SerializeMap> {
391        Ok(MapSerializer {
392            inner: Document::new(),
393            next_key: None,
394            options: self.options,
395        })
396    }
397
398    #[inline]
399    fn serialize_struct(
400        self,
401        _name: &'static str,
402        _len: usize,
403    ) -> crate::ser::Result<Self::SerializeStruct> {
404        Ok(StructSerializer {
405            inner: Document::new(),
406            options: self.options,
407        })
408    }
409
410    #[inline]
411    fn serialize_struct_variant(
412        self,
413        _name: &'static str,
414        _variant_index: u32,
415        variant: &'static str,
416        _len: usize,
417    ) -> crate::ser::Result<Self::SerializeStructVariant> {
418        Ok(StructVariantSerializer {
419            name: variant,
420            inner: Document::new(),
421            options: self.options,
422        })
423    }
424
425    fn is_human_readable(&self) -> bool {
426        self.options.human_readable.unwrap_or(true)
427    }
428}
429
430#[doc(hidden)]
431pub struct ArraySerializer {
432    inner: Array,
433    options: SerializerOptions,
434}
435
436impl SerializeSeq for ArraySerializer {
437    type Ok = Bson;
438    type Error = Error;
439
440    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> crate::ser::Result<()> {
441        self.inner
442            .push(to_bson_with_options(value, self.options.clone())?);
443        Ok(())
444    }
445
446    fn end(self) -> crate::ser::Result<Bson> {
447        Ok(Bson::Array(self.inner))
448    }
449}
450
451#[doc(hidden)]
452pub struct TupleSerializer {
453    inner: Array,
454    options: SerializerOptions,
455}
456
457impl SerializeTuple for TupleSerializer {
458    type Ok = Bson;
459    type Error = Error;
460
461    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> crate::ser::Result<()> {
462        self.inner
463            .push(to_bson_with_options(value, self.options.clone())?);
464        Ok(())
465    }
466
467    fn end(self) -> crate::ser::Result<Bson> {
468        Ok(Bson::Array(self.inner))
469    }
470}
471
472#[doc(hidden)]
473pub struct TupleStructSerializer {
474    inner: Array,
475    options: SerializerOptions,
476}
477
478impl SerializeTupleStruct for TupleStructSerializer {
479    type Ok = Bson;
480    type Error = Error;
481
482    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> crate::ser::Result<()> {
483        self.inner
484            .push(to_bson_with_options(value, self.options.clone())?);
485        Ok(())
486    }
487
488    fn end(self) -> crate::ser::Result<Bson> {
489        Ok(Bson::Array(self.inner))
490    }
491}
492
493#[doc(hidden)]
494pub struct TupleVariantSerializer {
495    inner: Array,
496    name: &'static str,
497    options: SerializerOptions,
498}
499
500impl SerializeTupleVariant for TupleVariantSerializer {
501    type Ok = Bson;
502    type Error = Error;
503
504    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> crate::ser::Result<()> {
505        self.inner
506            .push(to_bson_with_options(value, self.options.clone())?);
507        Ok(())
508    }
509
510    fn end(self) -> crate::ser::Result<Bson> {
511        let mut tuple_variant = Document::new();
512        tuple_variant.insert(self.name, self.inner);
513        Ok(tuple_variant.into())
514    }
515}
516
517#[doc(hidden)]
518pub struct MapSerializer {
519    inner: Document,
520    next_key: Option<String>,
521    options: SerializerOptions,
522}
523
524impl SerializeMap for MapSerializer {
525    type Ok = Bson;
526    type Error = Error;
527
528    fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<()> {
529        self.next_key = match to_bson_with_options(&key, self.options.clone())? {
530            Bson::String(s) => Some(s),
531            other => return Err(Error::invalid_key_type(other.element_type().name())),
532        };
533        Ok(())
534    }
535
536    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> crate::ser::Result<()> {
537        let key = self.next_key.take().unwrap_or_default();
538        self.inner
539            .insert(key, to_bson_with_options(&value, self.options.clone())?);
540        Ok(())
541    }
542
543    fn end(self) -> crate::ser::Result<Bson> {
544        Ok(Bson::from_extended_document(self.inner))
545    }
546}
547
548#[doc(hidden)]
549pub struct StructSerializer {
550    inner: Document,
551    options: SerializerOptions,
552}
553
554impl SerializeStruct for StructSerializer {
555    type Ok = Bson;
556    type Error = Error;
557
558    fn serialize_field<T: ?Sized + Serialize>(
559        &mut self,
560        key: &'static str,
561        value: &T,
562    ) -> crate::ser::Result<()> {
563        self.inner
564            .insert(key, to_bson_with_options(value, self.options.clone())?);
565        Ok(())
566    }
567
568    fn end(self) -> crate::ser::Result<Bson> {
569        Ok(Bson::from_extended_document(self.inner))
570    }
571}
572
573#[doc(hidden)]
574pub struct StructVariantSerializer {
575    inner: Document,
576    name: &'static str,
577    options: SerializerOptions,
578}
579
580impl SerializeStructVariant for StructVariantSerializer {
581    type Ok = Bson;
582    type Error = Error;
583
584    fn serialize_field<T: ?Sized + Serialize>(
585        &mut self,
586        key: &'static str,
587        value: &T,
588    ) -> crate::ser::Result<()> {
589        self.inner
590            .insert(key, to_bson_with_options(value, self.options.clone())?);
591        Ok(())
592    }
593
594    fn end(self) -> crate::ser::Result<Bson> {
595        let var = Bson::from_extended_document(self.inner);
596
597        let mut struct_variant = Document::new();
598        struct_variant.insert(self.name, var);
599
600        Ok(Bson::Document(struct_variant))
601    }
602}
603
604impl Serialize for Timestamp {
605    #[inline]
606    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
607    where
608        S: ser::Serializer,
609    {
610        let mut state = serializer.serialize_struct("$timestamp", 1)?;
611        let body = extjson::models::TimestampBody {
612            t: self.time,
613            i: self.increment,
614        };
615        state.serialize_field("$timestamp", &body)?;
616        state.end()
617    }
618}
619
620impl Serialize for Regex {
621    #[inline]
622    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
623    where
624        S: ser::Serializer,
625    {
626        let raw = RawRegexRef {
627            pattern: self.pattern.as_ref(),
628            options: self.options.as_ref(),
629        };
630        raw.serialize(serializer)
631    }
632}
633
634impl Serialize for JavaScriptCodeWithScope {
635    #[inline]
636    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
637    where
638        S: ser::Serializer,
639    {
640        let mut state = serializer.serialize_struct("$codeWithScope", 2)?;
641        state.serialize_field("$code", &self.code)?;
642        state.serialize_field("$scope", &self.scope)?;
643        state.end()
644    }
645}
646
647impl Serialize for Binary {
648    #[inline]
649    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
650    where
651        S: ser::Serializer,
652    {
653        if let BinarySubtype::Generic = self.subtype {
654            serializer.serialize_bytes(self.bytes.as_slice())
655        } else {
656            let mut state = serializer.serialize_struct("$binary", 1)?;
657            let body = extjson::models::BinaryBody {
658                base64: base64::encode(self.bytes.as_slice()),
659                subtype: hex::encode([self.subtype.into()]),
660            };
661            state.serialize_field("$binary", &body)?;
662            state.end()
663        }
664    }
665}
666
667impl Serialize for Decimal128 {
668    #[inline]
669    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
670    where
671        S: ser::Serializer,
672    {
673        let human_readable = serializer.is_human_readable();
674        let mut state = serializer.serialize_struct("$numberDecimal", 1)?;
675        if human_readable {
676            state.serialize_field("$numberDecimal", &self.to_string())?;
677        } else {
678            state.serialize_field("$numberDecimalBytes", serde_bytes::Bytes::new(&self.bytes))?;
679        }
680        state.end()
681    }
682}
683
684impl Serialize for DateTime {
685    #[inline]
686    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
687    where
688        S: ser::Serializer,
689    {
690        let mut state = serializer.serialize_struct("$date", 1)?;
691        let body = extjson::models::DateTimeBody::from_millis(self.timestamp_millis());
692        state.serialize_field("$date", &body)?;
693        state.end()
694    }
695}
696
697impl Serialize for DbPointer {
698    #[inline]
699    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
700    where
701        S: ser::Serializer,
702    {
703        let raw = RawDbPointerRef {
704            namespace: self.namespace.as_str(),
705            id: self.id,
706        };
707        raw.serialize(serializer)
708    }
709}