Move Content's Deserialize impl from serde_core to serde

This commit is contained in:
David Tolnay 2025-09-14 08:35:53 -07:00
parent cf141aa8c7
commit 00b1b6b2b5
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
5 changed files with 234 additions and 234 deletions

View File

@ -11,6 +11,7 @@ resolver = "2"
[patch.crates-io]
serde = { path = "serde" }
serde_core = { path = "serde_core" }
serde_derive = { path = "serde_derive" }
[workspace.dependencies]
proc-macro2 = { version = "1.0.74", default-features = false }

View File

@ -11,9 +11,10 @@ use crate::de::{MapAccess, Unexpected};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::content::{
content_as_str, Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer,
InternallyTaggedUnitVisitor, TagContentOtherField, TagContentOtherFieldVisitor,
TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor,
content_as_str, Content, ContentDeserializer, ContentRefDeserializer, ContentVisitor,
EnumDeserializer, InternallyTaggedUnitVisitor, TagContentOtherField,
TagContentOtherFieldVisitor, TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor,
UntaggedUnitVisitor,
};
pub use serde_core::__private::InPlaceSeed;
@ -212,8 +213,8 @@ mod content {
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
MapAccess, SeqAccess, Unexpected, Visitor,
};
use serde_core::__private::size_hint;
pub use serde_core::__private::Content;
use serde_core::__private::{size_hint, ContentVisitor};
pub fn content_as_str<'a, 'de>(content: &'a Content<'de>) -> Option<&'a str> {
match *content {
@ -283,6 +284,228 @@ mod content {
}
}
pub struct ContentVisitor<'de> {
value: PhantomData<Content<'de>>,
}
impl<'de> ContentVisitor<'de> {
pub fn new() -> Self {
ContentVisitor { value: PhantomData }
}
}
impl<'de> DeserializeSeed<'de> for ContentVisitor<'de> {
type Value = Content<'de>;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.__deserialize_content_v1(self)
}
}
impl<'de> Visitor<'de> for ContentVisitor<'de> {
type Value = Content<'de>;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("any value")
}
fn visit_bool<F>(self, value: bool) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Bool(value))
}
fn visit_i8<F>(self, value: i8) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I8(value))
}
fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I16(value))
}
fn visit_i32<F>(self, value: i32) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I32(value))
}
fn visit_i64<F>(self, value: i64) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I64(value))
}
fn visit_u8<F>(self, value: u8) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U8(value))
}
fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U16(value))
}
fn visit_u32<F>(self, value: u32) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U32(value))
}
fn visit_u64<F>(self, value: u64) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U64(value))
}
fn visit_f32<F>(self, value: f32) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::F32(value))
}
fn visit_f64<F>(self, value: f64) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::F64(value))
}
fn visit_char<F>(self, value: char) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Char(value))
}
fn visit_str<F>(self, value: &str) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::String(value.into()))
}
fn visit_borrowed_str<F>(self, value: &'de str) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Str(value))
}
fn visit_string<F>(self, value: String) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::String(value))
}
fn visit_bytes<F>(self, value: &[u8]) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::ByteBuf(value.into()))
}
fn visit_borrowed_bytes<F>(self, value: &'de [u8]) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Bytes(value))
}
fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::ByteBuf(value))
}
fn visit_unit<F>(self) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Unit)
}
fn visit_none<F>(self) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let v = tri!(ContentVisitor::new().deserialize(deserializer));
Ok(Content::Some(Box::new(v)))
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let v = tri!(ContentVisitor::new().deserialize(deserializer));
Ok(Content::Newtype(Box::new(v)))
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
let mut vec =
Vec::<Content>::with_capacity(size_hint::cautious::<Content>(visitor.size_hint()));
while let Some(e) = tri!(visitor.next_element_seed(ContentVisitor::new())) {
vec.push(e);
}
Ok(Content::Seq(vec))
}
fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
V: MapAccess<'de>,
{
let mut vec =
Vec::<(Content, Content)>::with_capacity(
size_hint::cautious::<(Content, Content)>(visitor.size_hint()),
);
while let Some(kv) =
tri!(visitor.next_entry_seed(ContentVisitor::new(), ContentVisitor::new()))
{
vec.push(kv);
}
Ok(Content::Map(vec))
}
fn visit_enum<V>(self, _visitor: V) -> Result<Self::Value, V::Error>
where
V: EnumAccess<'de>,
{
Err(de::Error::custom(
"untagged and internally tagged enums do not support enum input",
))
}
}
/// This is the type of the map keys in an internally tagged enum.
///
/// Not public API.
@ -622,7 +845,7 @@ mod content {
}
};
let rest = de::value::SeqAccessDeserializer::new(seq);
Ok((tag, tri!(Content::deserialize(rest))))
Ok((tag, tri!(ContentVisitor::new().deserialize(rest))))
}
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
@ -643,7 +866,7 @@ mod content {
tag = Some(tri!(map.next_value()));
}
TagOrContent::Content(k) => {
let v = tri!(map.next_value());
let v = tri!(map.next_value_seed(ContentVisitor::new()));
vec.push((k, v));
}
}

View File

@ -1,6 +1,4 @@
use crate::de::{self, Deserialize, Deserializer, EnumAccess, MapAccess, SeqAccess, Visitor};
use crate::lib::*;
use crate::private::size_hint;
// Used from generated code to buffer the contents of the Deserializer when
// deserializing untagged enums and internally tagged enums.
@ -39,225 +37,3 @@ pub enum Content<'de> {
Seq(Vec<Content<'de>>),
Map(Vec<(Content<'de>, Content<'de>)>),
}
impl<'de> Deserialize<'de> for Content<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
// Untagged and internally tagged enums are only supported in
// self-describing formats.
let visitor = ContentVisitor { value: PhantomData };
deserializer.__deserialize_content_v1(visitor)
}
}
#[doc(hidden)]
pub struct ContentVisitor<'de> {
value: PhantomData<Content<'de>>,
}
impl<'de> ContentVisitor<'de> {
pub fn new() -> Self {
ContentVisitor { value: PhantomData }
}
}
impl<'de> Visitor<'de> for ContentVisitor<'de> {
type Value = Content<'de>;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("any value")
}
fn visit_bool<F>(self, value: bool) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Bool(value))
}
fn visit_i8<F>(self, value: i8) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I8(value))
}
fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I16(value))
}
fn visit_i32<F>(self, value: i32) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I32(value))
}
fn visit_i64<F>(self, value: i64) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I64(value))
}
fn visit_u8<F>(self, value: u8) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U8(value))
}
fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U16(value))
}
fn visit_u32<F>(self, value: u32) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U32(value))
}
fn visit_u64<F>(self, value: u64) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U64(value))
}
fn visit_f32<F>(self, value: f32) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::F32(value))
}
fn visit_f64<F>(self, value: f64) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::F64(value))
}
fn visit_char<F>(self, value: char) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Char(value))
}
fn visit_str<F>(self, value: &str) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::String(value.into()))
}
fn visit_borrowed_str<F>(self, value: &'de str) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Str(value))
}
fn visit_string<F>(self, value: String) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::String(value))
}
fn visit_bytes<F>(self, value: &[u8]) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::ByteBuf(value.into()))
}
fn visit_borrowed_bytes<F>(self, value: &'de [u8]) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Bytes(value))
}
fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::ByteBuf(value))
}
fn visit_unit<F>(self) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Unit)
}
fn visit_none<F>(self) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let v = tri!(Deserialize::deserialize(deserializer));
Ok(Content::Some(Box::new(v)))
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let v = tri!(Deserialize::deserialize(deserializer));
Ok(Content::Newtype(Box::new(v)))
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
let mut vec =
Vec::<Content>::with_capacity(size_hint::cautious::<Content>(visitor.size_hint()));
while let Some(e) = tri!(visitor.next_element()) {
vec.push(e);
}
Ok(Content::Seq(vec))
}
fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
V: MapAccess<'de>,
{
let mut vec = Vec::<(Content, Content)>::with_capacity(size_hint::cautious::<(
Content,
Content,
)>(visitor.size_hint()));
while let Some(kv) = tri!(visitor.next_entry()) {
vec.push(kv);
}
Ok(Content::Map(vec))
}
fn visit_enum<V>(self, _visitor: V) -> Result<Self::Value, V::Error>
where
V: EnumAccess<'de>,
{
Err(de::Error::custom(
"untagged and internally tagged enums do not support enum input",
))
}
}

View File

@ -14,7 +14,7 @@ pub mod string;
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
#[doc(hidden)]
pub use self::content::{Content, ContentVisitor};
pub use self::content::Content;
#[doc(hidden)]
pub use self::seed::InPlaceSeed;
#[doc(hidden)]

View File

@ -1669,7 +1669,7 @@ fn deserialize_adjacently_tagged_enum(
// First key is the content.
_serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => {
// Buffer up the content.
let __content = _serde::de::MapAccess::next_value::<_serde::__private::de::Content>(&mut __map)?;
let __content = _serde::de::MapAccess::next_value_seed(&mut __map, _serde::__private::de::ContentVisitor::new())?;
// Visit the second key.
match #next_relevant_key {
// Second key is the tag.
@ -1789,7 +1789,7 @@ fn deserialize_untagged_enum_after(
});
quote_block! {
let __content = <_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer)?;
let __content = _serde::de::DeserializeSeed::deserialize(_serde::__private::de::ContentVisitor::new(), __deserializer)?;
let __deserializer = _serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content);
#first_attempt
@ -2592,7 +2592,7 @@ fn deserialize_map(
__Field::__other(__name) => {
__collect.push(_serde::__private::Some((
__name,
_serde::de::MapAccess::next_value(&mut __map)?)));
_serde::de::MapAccess::next_value_seed(&mut __map, _serde::__private::de::ContentVisitor::new())?)));
}
})
} else if cattrs.deny_unknown_fields() {