diff --git a/src/lib.rs b/src/lib.rs index ed29e7ff..43cfba1e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -474,6 +474,7 @@ pub use self::{ }, ser::{ serialize_to_bson, + serialize_to_buffer, serialize_to_document, serialize_to_raw_document_buf, serialize_to_vec, diff --git a/src/ser.rs b/src/ser.rs index ca829448..c391e7f7 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -89,7 +89,19 @@ pub fn serialize_to_vec(value: &T) -> Result> where T: Serialize, { - let mut serializer = raw::Serializer::new(); + let mut bytes = Vec::new(); + serialize_to_buffer(value, &mut bytes)?; + Ok(bytes) +} + +/// Serialize the given `T` as a BSON byte vector into the provided byte buffer. +/// This allows reusing the same buffer for multiple serializations. +#[inline] +pub fn serialize_to_buffer(value: &T, buffer: &mut Vec) -> Result<()> +where + T: Serialize, +{ + let mut serializer = raw::Serializer::new(buffer); #[cfg(feature = "serde_path_to_error")] { serde_path_to_error::serialize(value, &mut serializer).map_err(Error::with_path)?; @@ -98,7 +110,7 @@ where { value.serialize(&mut serializer)?; } - Ok(serializer.into_vec()) + Ok(()) } /// Serialize the given `T` as a [`RawDocumentBuf`]. diff --git a/src/ser/raw.rs b/src/ser/raw.rs index 73aec059..16e2e2c7 100644 --- a/src/ser/raw.rs +++ b/src/ser/raw.rs @@ -22,8 +22,11 @@ use crate::{ use document_serializer::DocumentSerializer; /// Serializer used to convert a type `T` into raw BSON bytes. -pub(crate) struct Serializer { - bytes: Vec, +pub(crate) struct Serializer<'a> { + bytes: &'a mut Vec, + + /// The index into `bytes` where the current serialization started. + start_index: usize, /// The index into `bytes` where the current element type will need to be stored. /// This needs to be set retroactively because in BSON, the element type comes before the key, @@ -58,21 +61,18 @@ impl SerializerHint { } } -impl Serializer { - pub(crate) fn new() -> Self { +impl<'a> Serializer<'a> { + pub(crate) fn new(bytes: &'a mut Vec) -> Self { + let start_index = bytes.len(); Self { - bytes: Vec::new(), - type_index: 0, + bytes, + start_index, + type_index: start_index, hint: SerializerHint::None, human_readable: false, } } - /// Convert this serializer into the vec of the serialized bytes. - pub(crate) fn into_vec(self) -> Vec { - self.bytes - } - /// Reserve a spot for the element type to be set retroactively via `update_element_type`. #[inline] fn reserve_element_type(&mut self) { @@ -83,7 +83,7 @@ impl Serializer { /// Retroactively set the element type of the most recently serialized element. #[inline] fn update_element_type(&mut self, t: ElementType) -> Result<()> { - if self.type_index == 0 { + if self.type_index == self.start_index { if matches!(t, ElementType::EmbeddedDocument) { // don't need to set the element type for the top level document return Ok(()); @@ -113,17 +113,17 @@ impl Serializer { } } -impl<'a> serde::Serializer for &'a mut Serializer { +impl<'a, 'b> serde::Serializer for &'a mut Serializer<'b> { type Ok = (); type Error = Error; - type SerializeSeq = DocumentSerializer<'a>; - type SerializeTuple = DocumentSerializer<'a>; - type SerializeTupleStruct = DocumentSerializer<'a>; - type SerializeTupleVariant = VariantSerializer<'a>; - type SerializeMap = DocumentSerializer<'a>; - type SerializeStruct = StructSerializer<'a>; - type SerializeStructVariant = VariantSerializer<'a>; + type SerializeSeq = DocumentSerializer<'a, 'b>; + type SerializeTuple = DocumentSerializer<'a, 'b>; + type SerializeTupleStruct = DocumentSerializer<'a, 'b>; + type SerializeTupleVariant = VariantSerializer<'a, 'b>; + type SerializeMap = DocumentSerializer<'a, 'b>; + type SerializeStruct = StructSerializer<'a, 'b>; + type SerializeStructVariant = VariantSerializer<'a, 'b>; fn is_human_readable(&self) -> bool { self.human_readable @@ -385,15 +385,15 @@ impl<'a> serde::Serializer for &'a mut Serializer { } } -pub(crate) enum StructSerializer<'a> { +pub(crate) enum StructSerializer<'a, 'b> { /// Serialize a BSON value currently represented in serde as a struct (e.g. ObjectId) - Value(ValueSerializer<'a>), + Value(ValueSerializer<'a, 'b>), /// Serialize the struct as a document. - Document(DocumentSerializer<'a>), + Document(DocumentSerializer<'a, 'b>), } -impl SerializeStruct for StructSerializer<'_> { +impl SerializeStruct for StructSerializer<'_, '_> { type Ok = (); type Error = Error; @@ -424,8 +424,8 @@ enum VariantInnerType { /// Serializer used for enum variants, including both tuple (e.g. Foo::Bar(1, 2, 3)) and /// struct (e.g. Foo::Bar { a: 1 }). -pub(crate) struct VariantSerializer<'a> { - root_serializer: &'a mut Serializer, +pub(crate) struct VariantSerializer<'a, 'b> { + root_serializer: &'a mut Serializer<'b>, /// Variants are serialized as documents of the form `{ : }`, /// and `doc_start` indicates the index at which the outer document begins. @@ -438,8 +438,8 @@ pub(crate) struct VariantSerializer<'a> { num_elements_serialized: usize, } -impl<'a> VariantSerializer<'a> { - fn start(rs: &'a mut Serializer, variant: &'static CStr, inner_type: VariantInnerType) -> Self { +impl<'a, 'b> VariantSerializer<'a, 'b> { + fn start(rs: &'a mut Serializer<'b>, variant: &'static CStr, inner_type: VariantInnerType) -> Self { let doc_start = rs.bytes.len(); // write placeholder length for document, will be updated at end static ZERO: RawBsonRef = RawBsonRef::Int32(0); @@ -492,7 +492,7 @@ impl<'a> VariantSerializer<'a> { } } -impl serde::ser::SerializeTupleVariant for VariantSerializer<'_> { +impl serde::ser::SerializeTupleVariant for VariantSerializer<'_, '_> { type Ok = (); type Error = Error; @@ -511,7 +511,7 @@ impl serde::ser::SerializeTupleVariant for VariantSerializer<'_> { } } -impl serde::ser::SerializeStructVariant for VariantSerializer<'_> { +impl serde::ser::SerializeStructVariant for VariantSerializer<'_, '_> { type Ok = (); type Error = Error; diff --git a/src/ser/raw/document_serializer.rs b/src/ser/raw/document_serializer.rs index a2317eb7..dc737670 100644 --- a/src/ser/raw/document_serializer.rs +++ b/src/ser/raw/document_serializer.rs @@ -7,19 +7,19 @@ use crate::{ use super::Serializer; -pub(crate) struct DocumentSerializationResult<'a> { - pub(crate) root_serializer: &'a mut Serializer, +pub(crate) struct DocumentSerializationResult<'a, 'b> { + pub(crate) root_serializer: &'a mut Serializer<'b>, } /// Serializer used to serialize document or array bodies. -pub(crate) struct DocumentSerializer<'a> { - root_serializer: &'a mut Serializer, +pub(crate) struct DocumentSerializer<'a, 'b> { + root_serializer: &'a mut Serializer<'b>, num_keys_serialized: usize, start: usize, } -impl<'a> DocumentSerializer<'a> { - pub(crate) fn start(rs: &'a mut Serializer) -> Self { +impl<'a, 'b> DocumentSerializer<'a, 'b> { + pub(crate) fn start(rs: &'a mut Serializer<'b>) -> Self { let start = rs.bytes.len(); RawBsonRef::Int32(0).append_to(&mut rs.bytes); Self { @@ -30,7 +30,7 @@ impl<'a> DocumentSerializer<'a> { } /// Serialize a document key using the provided closure. - fn serialize_doc_key_custom Result<()>>( + fn serialize_doc_key_custom) -> Result<()>>( &mut self, f: F, ) -> Result<()> { @@ -55,7 +55,7 @@ impl<'a> DocumentSerializer<'a> { Ok(()) } - pub(crate) fn end_doc(self) -> crate::ser::Result> { + pub(crate) fn end_doc(self) -> crate::ser::Result> { self.root_serializer.bytes.push(0); let length = (self.root_serializer.bytes.len() - self.start) as i32; self.root_serializer.replace_i32(self.start, length); @@ -65,7 +65,7 @@ impl<'a> DocumentSerializer<'a> { } } -impl serde::ser::SerializeSeq for DocumentSerializer<'_> { +impl serde::ser::SerializeSeq for DocumentSerializer<'_, '_> { type Ok = (); type Error = Error; @@ -90,7 +90,7 @@ impl serde::ser::SerializeSeq for DocumentSerializer<'_> { } } -impl serde::ser::SerializeMap for DocumentSerializer<'_> { +impl serde::ser::SerializeMap for DocumentSerializer<'_, '_> { type Ok = (); type Error = Error; @@ -116,7 +116,7 @@ impl serde::ser::SerializeMap for DocumentSerializer<'_> { } } -impl serde::ser::SerializeStruct for DocumentSerializer<'_> { +impl serde::ser::SerializeStruct for DocumentSerializer<'_, '_> { type Ok = (); type Error = Error; @@ -136,7 +136,7 @@ impl serde::ser::SerializeStruct for DocumentSerializer<'_> { } } -impl serde::ser::SerializeTuple for DocumentSerializer<'_> { +impl serde::ser::SerializeTuple for DocumentSerializer<'_, '_> { type Ok = (); type Error = Error; @@ -156,7 +156,7 @@ impl serde::ser::SerializeTuple for DocumentSerializer<'_> { } } -impl serde::ser::SerializeTupleStruct for DocumentSerializer<'_> { +impl serde::ser::SerializeTupleStruct for DocumentSerializer<'_, '_> { type Ok = (); type Error = Error; @@ -178,11 +178,11 @@ impl serde::ser::SerializeTupleStruct for DocumentSerializer<'_> { /// Serializer used specifically for serializing document keys. /// Only keys that serialize to strings will be accepted. -struct KeySerializer<'a> { - root_serializer: &'a mut Serializer, +struct KeySerializer<'a, 'b> { + root_serializer: &'a mut Serializer<'b>, } -impl serde::Serializer for KeySerializer<'_> { +impl serde::Serializer for KeySerializer<'_, '_> { type Ok = (); type Error = Error; diff --git a/src/ser/raw/value_serializer.rs b/src/ser/raw/value_serializer.rs index 5df7f4f4..41b791b5 100644 --- a/src/ser/raw/value_serializer.rs +++ b/src/ser/raw/value_serializer.rs @@ -21,8 +21,8 @@ use super::{document_serializer::DocumentSerializer, Serializer}; /// A serializer used specifically for serializing the serde-data-model form of a BSON type (e.g. /// [`Binary`]) to raw bytes. -pub(crate) struct ValueSerializer<'a> { - root_serializer: &'a mut Serializer, +pub(crate) struct ValueSerializer<'a, 'b> { + root_serializer: &'a mut Serializer<'b>, state: SerializationStep, } @@ -124,8 +124,8 @@ impl From for ElementType { } } -impl<'a> ValueSerializer<'a> { - pub(super) fn new(rs: &'a mut Serializer, value_type: ValueType) -> Self { +impl<'a, 'b> ValueSerializer<'a, 'b> { + pub(super) fn new(rs: &'a mut Serializer<'b>, value_type: ValueType) -> Self { let state = match value_type { ValueType::DateTime => SerializationStep::DateTime, ValueType::Binary => SerializationStep::Binary, @@ -155,7 +155,7 @@ impl<'a> ValueSerializer<'a> { } } -impl<'b> serde::Serializer for &'b mut ValueSerializer<'_> { +impl<'a, 'b> serde::Serializer for &'a mut ValueSerializer<'_, 'b> { type Ok = (); type Error = Error; @@ -163,7 +163,7 @@ impl<'b> serde::Serializer for &'b mut ValueSerializer<'_> { type SerializeTuple = Impossible<(), Error>; type SerializeTupleStruct = Impossible<(), Error>; type SerializeTupleVariant = Impossible<(), Error>; - type SerializeMap = CodeWithScopeSerializer<'b>; + type SerializeMap = CodeWithScopeSerializer<'a, 'b>; type SerializeStruct = Self; type SerializeStructVariant = Impossible<(), Error>; @@ -475,7 +475,7 @@ impl<'b> serde::Serializer for &'b mut ValueSerializer<'_> { } } -impl SerializeStruct for &mut ValueSerializer<'_> { +impl SerializeStruct for &mut ValueSerializer<'_, '_> { type Ok = (); type Error = Error; @@ -605,14 +605,14 @@ impl SerializeStruct for &mut ValueSerializer<'_> { } } -pub(crate) struct CodeWithScopeSerializer<'a> { +pub(crate) struct CodeWithScopeSerializer<'a, 'b> { start: usize, - doc: DocumentSerializer<'a>, + doc: DocumentSerializer<'a, 'b>, } -impl<'a> CodeWithScopeSerializer<'a> { +impl<'a, 'b> CodeWithScopeSerializer<'a, 'b> { #[inline] - fn start(code: &str, rs: &'a mut Serializer) -> Self { + fn start(code: &str, rs: &'a mut Serializer<'b>) -> Self { let start = rs.bytes.len(); RawBsonRef::Int32(0).append_to(&mut rs.bytes); // placeholder length write_string(&mut rs.bytes, code); @@ -622,7 +622,7 @@ impl<'a> CodeWithScopeSerializer<'a> { } } -impl SerializeMap for CodeWithScopeSerializer<'_> { +impl SerializeMap for CodeWithScopeSerializer<'_, '_> { type Ok = (); type Error = Error;