Expose types implementing `serde::Serializer` and `Deserializer` (#729)

* Expose types implementing serde::Deserializer

* Gate IoReader import
This commit is contained in:
Bogdan Opanchuk 2025-03-02 09:34:18 -10:00 committed by GitHub
parent 6a316617f4
commit 8e86cdfdd4
2 changed files with 103 additions and 42 deletions

View File

@ -1,12 +1,48 @@
use super::DecodeError as SerdeDecodeError; use super::DecodeError as SerdeDecodeError;
use crate::{ use crate::{
config::Config, config::Config,
de::{BorrowDecode, BorrowDecoder, Decode}, de::{read::SliceReader, BorrowDecode, BorrowDecoder, Decode, DecoderImpl},
error::DecodeError, error::DecodeError,
}; };
use core::marker::PhantomData; use core::marker::PhantomData;
use serde::de::*; 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<SliceReader<'de>, C>> {
/// Creates the decoder from a borrowed slice.
pub fn from_slice(
slice: &'de [u8],
config: C,
) -> BorrowedSerdeDecoder<'de, DecoderImpl<SliceReader<'de>, 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. /// 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. /// See the [config](../config/index.html) module for more information on configurations.
@ -18,14 +54,10 @@ where
D: Deserialize<'de>, D: Deserialize<'de>,
C: Config, C: Config,
{ {
let reader = crate::de::read::SliceReader::new(slice); let mut serde_decoder =
let mut decoder = crate::de::DecoderImpl::new(reader, config); BorrowedSerdeDecoder::<DecoderImpl<SliceReader<'de>, C>>::from_slice(slice, config);
let serde_decoder = SerdeDecoder { let result = D::deserialize(serde_decoder.as_deserializer())?;
de: &mut decoder, let bytes_read = slice.len() - serde_decoder.de.borrow_reader().slice.len();
pd: PhantomData,
};
let result = D::deserialize(serde_decoder)?;
let bytes_read = slice.len() - decoder.borrow_reader().slice.len();
Ok((result, bytes_read)) Ok((result, bytes_read))
} }
@ -36,13 +68,9 @@ where
T: Deserialize<'de>, T: Deserialize<'de>,
C: Config, C: Config,
{ {
let reader = crate::de::read::SliceReader::new(slice); let mut serde_decoder =
let mut decoder = crate::de::DecoderImpl::new(reader, config); BorrowedSerdeDecoder::<DecoderImpl<SliceReader<'de>, C>>::from_slice(slice, config);
let serde_decoder = SerdeDecoder { T::deserialize(serde_decoder.as_deserializer())
de: &mut decoder,
pd: PhantomData,
};
T::deserialize(serde_decoder)
} }
/// 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 /// 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>, T: DeserializeSeed<'de>,
C: Config, C: Config,
{ {
let reader = crate::de::read::SliceReader::new(slice); let mut serde_decoder =
let mut decoder = crate::de::DecoderImpl::new(reader, config); BorrowedSerdeDecoder::<DecoderImpl<SliceReader<'de>, C>>::from_slice(slice, config);
let serde_decoder = SerdeDecoder { seed.deserialize(serde_decoder.as_deserializer())
de: &mut decoder,
pd: PhantomData,
};
seed.deserialize(serde_decoder)
} }
pub(super) struct SerdeDecoder<'a, 'de, DE: BorrowDecoder<'de>> { pub(super) struct SerdeDecoder<'a, 'de, DE: BorrowDecoder<'de>> {

View File

@ -1,11 +1,55 @@
use super::DecodeError as SerdeDecodeError; use super::{de_borrowed::borrow_decode_from_slice, DecodeError as SerdeDecodeError};
use crate::{ use crate::{
config::Config, config::Config,
de::{read::Reader, Decode, Decoder}, de::{read::Reader, Decode, Decoder, DecoderImpl},
error::DecodeError, error::DecodeError,
}; };
use serde::de::*; use serde::de::*;
#[cfg(feature = "std")]
use crate::features::IoReader;
/// Serde decoder encapsulating an owned reader.
pub struct OwnedSerdeDecoder<DE: Decoder> {
pub(super) de: DE,
}
impl<DE: Decoder> OwnedSerdeDecoder<DE> {
/// 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<DecoderImpl<IoReader<&'r mut R>, C>> {
/// Creates the decoder from an `std::io::Read` implementor.
pub fn from_std_read(
src: &'r mut R,
config: C,
) -> OwnedSerdeDecoder<DecoderImpl<IoReader<&'r mut R>, C>>
where
C: Config,
{
let reader = IoReader::new(src);
let decoder = DecoderImpl::new(reader, config);
Self { de: decoder }
}
}
impl<C: Config, R: Reader> OwnedSerdeDecoder<DecoderImpl<R, C>> {
/// Creates the decoder from a [`Reader`] implementor.
pub fn from_reader(reader: R, config: C) -> OwnedSerdeDecoder<DecoderImpl<R, C>>
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. /// 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]. /// 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, D: DeserializeOwned,
C: Config, C: Config,
{ {
let reader = crate::de::read::SliceReader::new(slice); borrow_decode_from_slice(slice, config)
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))
} }
/// 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`. /// 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 /// [config]: ../config/index.html
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))] #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn decode_from_std_read<D: DeserializeOwned, C: Config, R: std::io::Read>( pub fn decode_from_std_read<'r, D: DeserializeOwned, C: Config, R: std::io::Read>(
src: &mut R, src: &'r mut R,
config: C, config: C,
) -> Result<D, DecodeError> { ) -> Result<D, DecodeError> {
let reader = crate::IoReader::new(src); let mut serde_decoder =
let mut decoder = crate::de::DecoderImpl::new(reader, config); OwnedSerdeDecoder::<DecoderImpl<IoReader<&'r mut R>, C>>::from_std_read(src, config);
let serde_decoder = SerdeDecoder { de: &mut decoder }; D::deserialize(serde_decoder.as_deserializer())
D::deserialize(serde_decoder)
} }
/// Attempt to decode a given type `D` from the given [Reader]. /// Attempt to decode a given type `D` from the given [Reader].
@ -53,13 +91,12 @@ pub fn decode_from_reader<D: DeserializeOwned, R: Reader, C: Config>(
reader: R, reader: R,
config: C, config: C,
) -> Result<D, DecodeError> { ) -> Result<D, DecodeError> {
let mut decoder = crate::de::DecoderImpl::<_, C>::new(reader, config); let mut serde_decoder = OwnedSerdeDecoder::<DecoderImpl<R, C>>::from_reader(reader, config);
let serde_decoder = SerdeDecoder { de: &mut decoder }; D::deserialize(serde_decoder.as_deserializer())
D::deserialize(serde_decoder)
} }
pub(crate) struct SerdeDecoder<'a, DE: Decoder> { pub(super) struct SerdeDecoder<'a, DE: Decoder> {
pub(crate) de: &'a mut DE, pub(super) de: &'a mut DE,
} }
impl<'de, DE: Decoder> Deserializer<'de> for SerdeDecoder<'_, DE> { impl<'de, DE: Decoder> Deserializer<'de> for SerdeDecoder<'_, DE> {