Skip to content

Commit

Permalink
Optimize deserialization of recursive buffered types
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Jan 1, 2022
1 parent ff259ec commit 56bd369
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
14 changes: 14 additions & 0 deletions serde/src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,20 @@ pub trait Deserializer<'de>: Sized {
fn is_human_readable(&self) -> bool {
true
}

// Not public API.
#[cfg(all(serde_derive, any(feature = "std", feature = "alloc")))]
#[doc(hidden)]
fn __deserialize_content<V>(
self,
_: ::actually_private::T,
visitor: V,
) -> Result<::private::de::Content<'de>, Self::Error>
where
V: Visitor<'de, Value = ::private::de::Content<'de>>,
{
self.deserialize_any(visitor)
}
}

////////////////////////////////////////////////////////////////////////////////
Expand Down
5 changes: 5 additions & 0 deletions serde/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,8 @@ extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;

#[cfg(all(serde_derive, any(feature = "std", feature = "alloc")))]
mod actually_private {
pub struct T;
}
29 changes: 27 additions & 2 deletions serde/src/private/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ mod content {
use lib::*;

use __private::size_hint;
use actually_private;
use de::{
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
MapAccess, SeqAccess, Unexpected, Visitor,
Expand All @@ -215,7 +216,7 @@ mod content {
/// deserializing untagged enums and internally tagged enums.
///
/// Not public API. Use serde-value instead.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Content<'de> {
Bool(bool),

Expand Down Expand Up @@ -294,7 +295,7 @@ mod content {
// Untagged and internally tagged enums are only supported in
// self-describing formats.
let visitor = ContentVisitor { value: PhantomData };
deserializer.deserialize_any(visitor)
deserializer.__deserialize_content(actually_private::T, visitor)
}
}

Expand Down Expand Up @@ -1427,6 +1428,18 @@ mod content {
drop(self);
visitor.visit_unit()
}

fn __deserialize_content<V>(
self,
_: actually_private::T,
visitor: V,
) -> Result<Content<'de>, Self::Error>
where
V: Visitor<'de, Value = Content<'de>>,
{
let _ = visitor;
Ok(self.content)
}
}

impl<'de, E> ContentDeserializer<'de, E> {
Expand Down Expand Up @@ -2138,6 +2151,18 @@ mod content {
{
visitor.visit_unit()
}

fn __deserialize_content<V>(
self,
_: actually_private::T,
visitor: V,
) -> Result<Content<'de>, Self::Error>
where
V: Visitor<'de, Value = Content<'de>>,
{
let _ = visitor;
Ok(self.content.clone())
}
}

impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> {
Expand Down

0 comments on commit 56bd369

Please sign in to comment.