From 902142b17dda751b9af5d438eaef57b6136a8a39 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Sat, 9 Sep 2023 13:22:28 -0500 Subject: [PATCH] Cleanup interface --- src/de/mod.rs | 83 +++++++++++++++++++++++++++++---------------------- src/lib.rs | 2 +- 2 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/de/mod.rs b/src/de/mod.rs index ad8de46..9d4f028 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -54,52 +54,63 @@ where } /// Deserialize a type from an implementation of [`Read`]. -pub fn from_reader(mut reader: &mut impl Read) -> Result +pub fn from_reader(reader: &mut impl Read) -> Result where T: DeserializeOwned, { - let mut deserializer = Deserializer::from_reader(&mut reader, crate::MAX_CONTAINER_DEPTH); + let mut deserializer = Deserializer::from_reader(reader, crate::MAX_CONTAINER_DEPTH); T::deserialize(&mut deserializer) } +/// Deserialize a type from an implementation of [`Read`] using the provided seed +pub fn from_reader_seed( + seed: T, + reader: &mut impl Read, +) -> Result<>::Value> +where + for<'a> T: DeserializeSeed<'a>, +{ + let mut deserializer = Deserializer::from_reader(reader, crate::MAX_CONTAINER_DEPTH); + seed.deserialize(&mut deserializer) +} + /// Deserialization implementation for BCS -struct Deserializer<'de, R> { +struct Deserializer { input: R, max_remaining_depth: usize, - _phantom: std::marker::PhantomData<&'de ()>, } -impl<'de, R: Read> Deserializer<'de, TeeReader<&'de mut R>> { +impl<'de, R: Read> Deserializer> { fn from_reader(input: &'de mut R, max_remaining_depth: usize) -> Self { Deserializer { input: TeeReader::new(input), max_remaining_depth, - _phantom: std::marker::PhantomData, } } } -impl<'de> Deserializer<'de, &'de [u8]> { +impl<'de> Deserializer<&'de [u8]> { /// Creates a new `Deserializer` which will be deserializing the provided /// input. fn new(input: &'de [u8], max_remaining_depth: usize) -> Self { Deserializer { input, max_remaining_depth, - _phantom: std::marker::PhantomData, } } } /// A reader that can optionally capture all bytes from an underlying [`Read`]er -struct TeeReader { - reader: R, +struct TeeReader<'de, R> { + /// the underlying reader + reader: &'de mut R, + /// If set, all bytes read from the underlying reader will be duplicated here capture_buffer: Option>, } -impl TeeReader { +impl<'de, R> TeeReader<'de, R> { /// Wrapse the provided reader in a new [`TeeReader`]. - pub fn new(reader: R) -> Self { + pub fn new(reader: &'de mut R) -> Self { Self { reader, capture_buffer: Default::default(), @@ -107,7 +118,7 @@ impl TeeReader { } } -impl Read for TeeReader { +impl<'de, R: Read> Read for TeeReader<'de, R> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { let bytes_read = self.reader.read(buf)?; if let Some(ref mut buffer) = self.capture_buffer { @@ -211,7 +222,7 @@ trait BcsDeserializer<'de> { } } -impl<'de, R: Read> Deserializer<'de, TeeReader> { +impl<'de, R: Read> Deserializer> { fn parse_vec(&mut self) -> Result> { let len = self.parse_length()?; let mut output = vec![0; len]; @@ -225,7 +236,7 @@ impl<'de, R: Read> Deserializer<'de, TeeReader> { } } -impl<'de, R: Read> BcsDeserializer<'de> for Deserializer<'de, TeeReader> { +impl<'de, R: Read> BcsDeserializer<'de> for Deserializer> { type MaybeBorrowedBytes = Vec; fn fill_slice(&mut self, slice: &mut [u8]) -> Result<()> { @@ -257,7 +268,7 @@ impl<'de, R: Read> BcsDeserializer<'de> for Deserializer<'de, TeeReader> { } } -impl<'de> BcsDeserializer<'de> for Deserializer<'de, &'de [u8]> { +impl<'de> BcsDeserializer<'de> for Deserializer<&'de [u8]> { type MaybeBorrowedBytes = &'de [u8]; fn next(&mut self) -> Result { let byte = self.peek()?; @@ -298,7 +309,7 @@ impl<'de> BcsDeserializer<'de> for Deserializer<'de, &'de [u8]> { } } -impl<'de> Deserializer<'de, &'de [u8]> { +impl<'de> Deserializer<&'de [u8]> { fn peek(&mut self) -> Result { self.input.first().copied().ok_or(Error::Eof) } @@ -327,7 +338,7 @@ impl<'de> Deserializer<'de, &'de [u8]> { } } -impl<'de, R> Deserializer<'de, R> { +impl<'de, R> Deserializer { fn enter_named_container(&mut self, name: &'static str) -> Result<()> { if self.max_remaining_depth == 0 { return Err(Error::ExceededContainerDepthLimit(name)); @@ -341,9 +352,9 @@ impl<'de, R> Deserializer<'de, R> { } } -impl<'de, 'a, R> de::Deserializer<'de> for &'a mut Deserializer<'de, R> +impl<'de, 'a, R> de::Deserializer<'de> for &'a mut Deserializer where - Deserializer<'de, R>: BcsDeserializer<'de>, + Deserializer: BcsDeserializer<'de>, { type Error = Error; @@ -611,20 +622,20 @@ where } } -struct SeqDeserializer<'a, 'de: 'a, R> { - de: &'a mut Deserializer<'de, R>, +struct SeqDeserializer<'a, R> { + de: &'a mut Deserializer, remaining: usize, } #[allow(clippy::needless_borrow)] -impl<'a, 'de, R> SeqDeserializer<'a, 'de, R> { - fn new(de: &'a mut Deserializer<'de, R>, remaining: usize) -> Self { +impl<'a, R> SeqDeserializer<'a, R> { + fn new(de: &'a mut Deserializer, remaining: usize) -> Self { Self { de, remaining } } } -impl<'de, 'a, R> de::SeqAccess<'de> for SeqDeserializer<'a, 'de, R> +impl<'a, 'de, R> de::SeqAccess<'de> for SeqDeserializer<'a, R> where - Deserializer<'de, R>: BcsDeserializer<'de>, + Deserializer: BcsDeserializer<'de>, { type Error = Error; @@ -645,14 +656,14 @@ where } } -struct MapDeserializer<'a, 'de: 'a, R, B> { - de: &'a mut Deserializer<'de, R>, +struct MapDeserializer<'a, R, B> { + de: &'a mut Deserializer, remaining: usize, previous_key_bytes: Option, } -impl<'a, 'de, R, B> MapDeserializer<'a, 'de, R, B> { - fn new(de: &'a mut Deserializer<'de, R>, remaining: usize) -> Self { +impl<'a, R, B> MapDeserializer<'a, R, B> { + fn new(de: &'a mut Deserializer, remaining: usize) -> Self { Self { de, remaining, @@ -661,9 +672,9 @@ impl<'a, 'de, R, B> MapDeserializer<'a, 'de, R, B> { } } -impl<'de, 'a, R, B: AsRef<[u8]>> de::MapAccess<'de> for MapDeserializer<'a, 'de, R, B> +impl<'de, 'a, R, B: AsRef<[u8]>> de::MapAccess<'de> for MapDeserializer<'a, R, B> where - Deserializer<'de, R>: BcsDeserializer<'de, MaybeBorrowedBytes = B>, + Deserializer: BcsDeserializer<'de, MaybeBorrowedBytes = B>, { type Error = Error; @@ -699,9 +710,9 @@ where } } -impl<'de, 'a, R> de::EnumAccess<'de> for &'a mut Deserializer<'de, R> +impl<'de, 'a, R> de::EnumAccess<'de> for &'a mut Deserializer where - Deserializer<'de, R>: BcsDeserializer<'de>, + Deserializer: BcsDeserializer<'de>, { type Error = Error; type Variant = Self; @@ -716,9 +727,9 @@ where } } -impl<'de, 'a, R> de::VariantAccess<'de> for &'a mut Deserializer<'de, R> +impl<'de, 'a, R> de::VariantAccess<'de> for &'a mut Deserializer where - Deserializer<'de, R>: BcsDeserializer<'de>, + Deserializer: BcsDeserializer<'de>, { type Error = Error; diff --git a/src/lib.rs b/src/lib.rs index 3f4d452..6e4feec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -314,6 +314,6 @@ pub const MAX_SEQUENCE_LENGTH: usize = (1 << 31) - 1; /// Maximal allowed depth of BCS data, counting only structs and enums. pub const MAX_CONTAINER_DEPTH: usize = 500; -pub use de::{from_bytes, from_bytes_seed, from_reader}; +pub use de::{from_bytes, from_bytes_seed, from_reader, from_reader_seed}; pub use error::{Error, Result}; pub use ser::{is_human_readable, serialize_into, serialized_size, to_bytes};