Skip to content

Commit

Permalink
Expose types implementing serde::Deserializer
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Oct 30, 2024
1 parent 980f638 commit f286ab3
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 41 deletions.
70 changes: 47 additions & 23 deletions src/features/serde/de_borrowed.rs
Original file line number Diff line number Diff line change
@@ -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<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.
///
/// See the [config](../config/index.html) module for more information on configurations.
Expand All @@ -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::<DecoderImpl<SliceReader<'de>, 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))
}

Expand All @@ -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::<DecoderImpl<SliceReader<'de>, 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
Expand All @@ -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::<DecoderImpl<SliceReader<'de>, C>>::from_slice(slice, config);
seed.deserialize(serde_decoder.as_deserializer())
}

pub(super) struct SerdeDecoder<'a, 'de, DE: BorrowDecoder<'de>> {
Expand Down
73 changes: 55 additions & 18 deletions src/features/serde/de_owned.rs
Original file line number Diff line number Diff line change
@@ -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<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.
///
/// Note that this does not work with borrowed types like `&str` or `&[u8]`. For that use [borrow_decode_from_slice].
Expand All @@ -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`.
Expand All @@ -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<D: DeserializeOwned, C: Config, R: std::io::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<D, DecodeError> {
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::<DecoderImpl<IoReader<&'r mut R>, C>>::from_std_read(src, config);
D::deserialize(serde_decoder.as_deserializer())
}

/// Attempt to decode a given type `D` from the given [Reader].
Expand All @@ -53,13 +91,12 @@ pub fn decode_from_reader<D: DeserializeOwned, R: Reader, C: Config>(
reader: R,
config: C,
) -> Result<D, DecodeError> {
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::<DecoderImpl<R, C>>::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> {
Expand Down

0 comments on commit f286ab3

Please sign in to comment.