From f286ab3a05311337da7a8c4e534332d09252636b Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Sun, 27 Oct 2024 15:54:23 -0700 Subject: [PATCH] Expose types implementing serde::Deserializer --- src/features/serde/de_borrowed.rs | 70 +++++++++++++++++++---------- src/features/serde/de_owned.rs | 73 +++++++++++++++++++++++-------- 2 files changed, 102 insertions(+), 41 deletions(-) diff --git a/src/features/serde/de_borrowed.rs b/src/features/serde/de_borrowed.rs index 093a1984..bbff29e9 100644 --- a/src/features/serde/de_borrowed.rs +++ b/src/features/serde/de_borrowed.rs @@ -1,12 +1,48 @@ use super::DecodeError as SerdeDecodeError; use crate::{ config::Config, - de::{BorrowDecode, BorrowDecoder, Decode}, + de::{read::SliceReader, BorrowDecode, BorrowDecoder, Decode, DecoderImpl}, error::DecodeError, }; use core::marker::PhantomData; use serde::de::*; +/// Serde decoder encapsulating a borrowed reader. +pub struct BorrowedSerdeDecoder<'de, DE: BorrowDecoder<'de>> { + pub(super) de: DE, + pub(super) pd: PhantomData<&'de ()>, +} + +impl<'de, DE: BorrowDecoder<'de>> BorrowedSerdeDecoder<'de, DE> { + /// Return a type implementing `serde::Deserializer`. + pub fn as_deserializer<'a>( + &'a mut self, + ) -> impl serde::Deserializer<'de, Error = DecodeError> + 'a { + SerdeDecoder { + de: &mut self.de, + pd: PhantomData, + } + } +} + +impl<'de, C: Config> BorrowedSerdeDecoder<'de, DecoderImpl, C>> { + /// Creates the decoder from a borrowed slice. + pub fn from_slice( + slice: &'de [u8], + config: C, + ) -> BorrowedSerdeDecoder<'de, DecoderImpl, C>> + where + C: Config, + { + let reader = SliceReader::new(slice); + let decoder = DecoderImpl::new(reader, config); + Self { + de: decoder, + pd: PhantomData, + } + } +} + /// Attempt to decode a given type `D` from the given slice. Returns the decoded output and the amount of bytes read. /// /// See the [config](../config/index.html) module for more information on configurations. @@ -18,14 +54,10 @@ where D: Deserialize<'de>, C: Config, { - let reader = crate::de::read::SliceReader::new(slice); - let mut decoder = crate::de::DecoderImpl::new(reader, config); - let serde_decoder = SerdeDecoder { - de: &mut decoder, - pd: PhantomData, - }; - let result = D::deserialize(serde_decoder)?; - let bytes_read = slice.len() - decoder.borrow_reader().slice.len(); + let mut serde_decoder = + BorrowedSerdeDecoder::, C>>::from_slice(slice, config); + let result = D::deserialize(serde_decoder.as_deserializer())?; + let bytes_read = slice.len() - serde_decoder.de.borrow_reader().slice.len(); Ok((result, bytes_read)) } @@ -36,13 +68,9 @@ where T: Deserialize<'de>, C: Config, { - let reader = crate::de::read::SliceReader::new(slice); - let mut decoder = crate::de::DecoderImpl::new(reader, config); - let serde_decoder = SerdeDecoder { - de: &mut decoder, - pd: PhantomData, - }; - T::deserialize(serde_decoder) + let mut serde_decoder = + BorrowedSerdeDecoder::, C>>::from_slice(slice, config); + T::deserialize(serde_decoder.as_deserializer()) } /// Decode a borrowed type from the given slice using a seed. Some parts of the decoded type are expected to be referring to the given slice @@ -55,13 +83,9 @@ where T: DeserializeSeed<'de>, C: Config, { - let reader = crate::de::read::SliceReader::new(slice); - let mut decoder = crate::de::DecoderImpl::new(reader, config); - let serde_decoder = SerdeDecoder { - de: &mut decoder, - pd: PhantomData, - }; - seed.deserialize(serde_decoder) + let mut serde_decoder = + BorrowedSerdeDecoder::, C>>::from_slice(slice, config); + seed.deserialize(serde_decoder.as_deserializer()) } pub(super) struct SerdeDecoder<'a, 'de, DE: BorrowDecoder<'de>> { diff --git a/src/features/serde/de_owned.rs b/src/features/serde/de_owned.rs index 502a92a5..c39a20ec 100644 --- a/src/features/serde/de_owned.rs +++ b/src/features/serde/de_owned.rs @@ -1,11 +1,55 @@ use super::DecodeError as SerdeDecodeError; use crate::{ config::Config, - de::{read::Reader, Decode, Decoder}, + de::{read::Reader, Decode, Decoder, DecoderImpl}, error::DecodeError, + IoReader, }; use serde::de::*; +use super::de_borrowed::borrow_decode_from_slice; + +/// Serde decoder encapsulating an owned reader. +pub struct OwnedSerdeDecoder { + pub(super) de: DE, +} + +impl OwnedSerdeDecoder { + /// Return a type implementing `serde::Deserializer`. + pub fn as_deserializer<'a>( + &'a mut self, + ) -> impl for<'de> serde::Deserializer<'de, Error = DecodeError> + 'a { + SerdeDecoder { de: &mut self.de } + } +} + +#[cfg(feature = "std")] +impl<'r, C: Config, R: std::io::Read> OwnedSerdeDecoder, C>> { + /// Creates the decoder from an `std::io::Read` implementor. + pub fn from_std_read( + src: &'r mut R, + config: C, + ) -> OwnedSerdeDecoder, C>> + where + C: Config, + { + let reader = IoReader::new(src); + let decoder = DecoderImpl::new(reader, config); + Self { de: decoder } + } +} + +impl OwnedSerdeDecoder> { + /// Creates the decoder from a [`Reader`] implementor. + pub fn from_reader(reader: R, config: C) -> OwnedSerdeDecoder> + where + C: Config, + { + let decoder = DecoderImpl::new(reader, config); + Self { de: decoder } + } +} + /// Attempt to decode a given type `D` from the given slice. Returns the decoded output and the amount of bytes read. /// /// Note that this does not work with borrowed types like `&str` or `&[u8]`. For that use [borrow_decode_from_slice]. @@ -19,12 +63,7 @@ where D: DeserializeOwned, C: Config, { - let reader = crate::de::read::SliceReader::new(slice); - let mut decoder = crate::de::DecoderImpl::new(reader, config); - let serde_decoder = SerdeDecoder { de: &mut decoder }; - let result = D::deserialize(serde_decoder)?; - let bytes_read = slice.len() - decoder.reader().slice.len(); - Ok((result, bytes_read)) + borrow_decode_from_slice(slice, config) } /// Decode type `D` from the given reader with the given `Config`. The reader can be any type that implements `std::io::Read`, e.g. `std::fs::File`. @@ -34,14 +73,13 @@ where /// [config]: ../config/index.html #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] -pub fn decode_from_std_read( - src: &mut R, +pub fn decode_from_std_read<'r, D: DeserializeOwned, C: Config, R: std::io::Read>( + src: &'r mut R, config: C, ) -> Result { - let reader = crate::IoReader::new(src); - let mut decoder = crate::de::DecoderImpl::new(reader, config); - let serde_decoder = SerdeDecoder { de: &mut decoder }; - D::deserialize(serde_decoder) + let mut serde_decoder = + OwnedSerdeDecoder::, C>>::from_std_read(src, config); + D::deserialize(serde_decoder.as_deserializer()) } /// Attempt to decode a given type `D` from the given [Reader]. @@ -53,13 +91,12 @@ pub fn decode_from_reader( reader: R, config: C, ) -> Result { - let mut decoder = crate::de::DecoderImpl::<_, C>::new(reader, config); - let serde_decoder = SerdeDecoder { de: &mut decoder }; - D::deserialize(serde_decoder) + let mut serde_decoder = OwnedSerdeDecoder::>::from_reader(reader, config); + D::deserialize(serde_decoder.as_deserializer()) } -pub(crate) struct SerdeDecoder<'a, DE: Decoder> { - pub(crate) de: &'a mut DE, +pub(super) struct SerdeDecoder<'a, DE: Decoder> { + pub(super) de: &'a mut DE, } impl<'a, 'de, DE: Decoder> Deserializer<'de> for SerdeDecoder<'a, DE> {