Skip to content

Commit 9eaf7b9

Browse files
authored
Merge pull request #2805 from Mingun/untagged-tests
Fix deserialization of empty structs and tuples in untagged enums
2 parents 31ca16d + 7bde100 commit 9eaf7b9

File tree

4 files changed

+621
-560
lines changed

4 files changed

+621
-560
lines changed

serde/src/private/de.rs

+37-161
Original file line numberDiff line numberDiff line change
@@ -1898,10 +1898,17 @@ mod content {
18981898
where
18991899
V: Visitor<'de>,
19001900
{
1901+
// Covered by tests/test_enum_untagged.rs
1902+
// with_optional_field::*
19011903
match *self.content {
19021904
Content::None => visitor.visit_none(),
19031905
Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)),
19041906
Content::Unit => visitor.visit_unit(),
1907+
// This case is necessary for formats which does not store marker of optionality of value,
1908+
// for example, JSON. When `deserialize_any` is requested from such formats, they will
1909+
// report value without using `Visitor::visit_some`, because they do not known in which
1910+
// contexts this value will be used.
1911+
// RON is example of format which preserve markers.
19051912
_ => visitor.visit_some(self),
19061913
}
19071914
}
@@ -1931,10 +1938,17 @@ mod content {
19311938
where
19321939
V: Visitor<'de>,
19331940
{
1941+
// Covered by tests/test_enum_untagged.rs
1942+
// newtype_struct
19341943
match *self.content {
19351944
Content::Newtype(ref v) => {
19361945
visitor.visit_newtype_struct(ContentRefDeserializer::new(v))
19371946
}
1947+
// This case is necessary for formats which does not store marker of a newtype,
1948+
// for example, JSON. When `deserialize_any` is requested from such formats, they will
1949+
// report value without using `Visitor::visit_newtype_struct`, because they do not
1950+
// known in which contexts this value will be used.
1951+
// RON is example of format which preserve markers.
19381952
_ => visitor.visit_newtype_struct(self),
19391953
}
19401954
}
@@ -2139,6 +2153,10 @@ mod content {
21392153
fn unit_variant(self) -> Result<(), E> {
21402154
match self.value {
21412155
Some(value) => de::Deserialize::deserialize(ContentRefDeserializer::new(value)),
2156+
// Covered by tests/test_annotations.rs
2157+
// test_partially_untagged_adjacently_tagged_enum
2158+
// Covered by tests/test_enum_untagged.rs
2159+
// newtype_enum::unit
21422160
None => Ok(()),
21432161
}
21442162
}
@@ -2148,6 +2166,11 @@ mod content {
21482166
T: de::DeserializeSeed<'de>,
21492167
{
21502168
match self.value {
2169+
// Covered by tests/test_annotations.rs
2170+
// test_partially_untagged_enum_desugared
2171+
// test_partially_untagged_enum_generic
2172+
// Covered by tests/test_enum_untagged.rs
2173+
// newtype_enum::newtype
21512174
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
21522175
None => Err(de::Error::invalid_type(
21532176
de::Unexpected::UnitVariant,
@@ -2161,9 +2184,13 @@ mod content {
21612184
V: de::Visitor<'de>,
21622185
{
21632186
match self.value {
2164-
Some(Content::Seq(v)) => {
2165-
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
2166-
}
2187+
// Covered by tests/test_annotations.rs
2188+
// test_partially_untagged_enum
2189+
// test_partially_untagged_enum_desugared
2190+
// Covered by tests/test_enum_untagged.rs
2191+
// newtype_enum::tuple0
2192+
// newtype_enum::tuple2
2193+
Some(Content::Seq(v)) => visit_content_seq_ref(v, visitor),
21672194
Some(other) => Err(de::Error::invalid_type(
21682195
other.unexpected(),
21692196
&"tuple variant",
@@ -2184,12 +2211,13 @@ mod content {
21842211
V: de::Visitor<'de>,
21852212
{
21862213
match self.value {
2187-
Some(Content::Map(v)) => {
2188-
de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
2189-
}
2190-
Some(Content::Seq(v)) => {
2191-
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
2192-
}
2214+
// Covered by tests/test_enum_untagged.rs
2215+
// newtype_enum::struct_from_map
2216+
Some(Content::Map(v)) => visit_content_map_ref(v, visitor),
2217+
// Covered by tests/test_enum_untagged.rs
2218+
// newtype_enum::struct_from_seq
2219+
// newtype_enum::empty_struct_from_seq
2220+
Some(Content::Seq(v)) => visit_content_seq_ref(v, visitor),
21932221
Some(other) => Err(de::Error::invalid_type(
21942222
other.unexpected(),
21952223
&"struct variant",
@@ -2202,158 +2230,6 @@ mod content {
22022230
}
22032231
}
22042232

2205-
struct SeqRefDeserializer<'a, 'de: 'a, E>
2206-
where
2207-
E: de::Error,
2208-
{
2209-
iter: <&'a [Content<'de>] as IntoIterator>::IntoIter,
2210-
err: PhantomData<E>,
2211-
}
2212-
2213-
impl<'a, 'de, E> SeqRefDeserializer<'a, 'de, E>
2214-
where
2215-
E: de::Error,
2216-
{
2217-
fn new(slice: &'a [Content<'de>]) -> Self {
2218-
SeqRefDeserializer {
2219-
iter: slice.iter(),
2220-
err: PhantomData,
2221-
}
2222-
}
2223-
}
2224-
2225-
impl<'de, 'a, E> de::Deserializer<'de> for SeqRefDeserializer<'a, 'de, E>
2226-
where
2227-
E: de::Error,
2228-
{
2229-
type Error = E;
2230-
2231-
#[inline]
2232-
fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
2233-
where
2234-
V: de::Visitor<'de>,
2235-
{
2236-
let len = self.iter.len();
2237-
if len == 0 {
2238-
visitor.visit_unit()
2239-
} else {
2240-
let ret = tri!(visitor.visit_seq(&mut self));
2241-
let remaining = self.iter.len();
2242-
if remaining == 0 {
2243-
Ok(ret)
2244-
} else {
2245-
Err(de::Error::invalid_length(len, &"fewer elements in array"))
2246-
}
2247-
}
2248-
}
2249-
2250-
forward_to_deserialize_any! {
2251-
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
2252-
bytes byte_buf option unit unit_struct newtype_struct seq tuple
2253-
tuple_struct map struct enum identifier ignored_any
2254-
}
2255-
}
2256-
2257-
impl<'de, 'a, E> de::SeqAccess<'de> for SeqRefDeserializer<'a, 'de, E>
2258-
where
2259-
E: de::Error,
2260-
{
2261-
type Error = E;
2262-
2263-
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
2264-
where
2265-
T: de::DeserializeSeed<'de>,
2266-
{
2267-
match self.iter.next() {
2268-
Some(value) => seed
2269-
.deserialize(ContentRefDeserializer::new(value))
2270-
.map(Some),
2271-
None => Ok(None),
2272-
}
2273-
}
2274-
2275-
fn size_hint(&self) -> Option<usize> {
2276-
size_hint::from_bounds(&self.iter)
2277-
}
2278-
}
2279-
2280-
struct MapRefDeserializer<'a, 'de: 'a, E>
2281-
where
2282-
E: de::Error,
2283-
{
2284-
iter: <&'a [(Content<'de>, Content<'de>)] as IntoIterator>::IntoIter,
2285-
value: Option<&'a Content<'de>>,
2286-
err: PhantomData<E>,
2287-
}
2288-
2289-
impl<'a, 'de, E> MapRefDeserializer<'a, 'de, E>
2290-
where
2291-
E: de::Error,
2292-
{
2293-
fn new(map: &'a [(Content<'de>, Content<'de>)]) -> Self {
2294-
MapRefDeserializer {
2295-
iter: map.iter(),
2296-
value: None,
2297-
err: PhantomData,
2298-
}
2299-
}
2300-
}
2301-
2302-
impl<'de, 'a, E> de::MapAccess<'de> for MapRefDeserializer<'a, 'de, E>
2303-
where
2304-
E: de::Error,
2305-
{
2306-
type Error = E;
2307-
2308-
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
2309-
where
2310-
T: de::DeserializeSeed<'de>,
2311-
{
2312-
match self.iter.next() {
2313-
Some((key, value)) => {
2314-
self.value = Some(value);
2315-
seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
2316-
}
2317-
None => Ok(None),
2318-
}
2319-
}
2320-
2321-
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
2322-
where
2323-
T: de::DeserializeSeed<'de>,
2324-
{
2325-
match self.value.take() {
2326-
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
2327-
None => Err(de::Error::custom("value is missing")),
2328-
}
2329-
}
2330-
2331-
fn size_hint(&self) -> Option<usize> {
2332-
size_hint::from_bounds(&self.iter)
2333-
}
2334-
}
2335-
2336-
impl<'de, 'a, E> de::Deserializer<'de> for MapRefDeserializer<'a, 'de, E>
2337-
where
2338-
E: de::Error,
2339-
{
2340-
type Error = E;
2341-
2342-
#[inline]
2343-
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
2344-
where
2345-
V: de::Visitor<'de>,
2346-
{
2347-
visitor.visit_map(self)
2348-
}
2349-
2350-
forward_to_deserialize_any! {
2351-
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
2352-
bytes byte_buf option unit unit_struct newtype_struct seq tuple
2353-
tuple_struct map struct enum identifier ignored_any
2354-
}
2355-
}
2356-
23572233
impl<'de, E> de::IntoDeserializer<'de, E> for ContentDeserializer<'de, E>
23582234
where
23592235
E: de::Error,

test_suite/tests/test_annotations.rs

-47
Original file line numberDiff line numberDiff line change
@@ -1895,18 +1895,6 @@ fn test_expecting_message_externally_tagged_enum() {
18951895
);
18961896
}
18971897

1898-
#[test]
1899-
fn test_expecting_message_untagged_tagged_enum() {
1900-
#[derive(Deserialize)]
1901-
#[serde(untagged)]
1902-
#[serde(expecting = "something strange...")]
1903-
enum Enum {
1904-
Untagged,
1905-
}
1906-
1907-
assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], "something strange...");
1908-
}
1909-
19101898
#[test]
19111899
fn test_expecting_message_identifier_enum() {
19121900
#[derive(Deserialize)]
@@ -2958,41 +2946,6 @@ mod flatten {
29582946
mod untagged {
29592947
use super::*;
29602948

2961-
#[test]
2962-
fn straightforward() {
2963-
#[derive(Serialize, Deserialize, PartialEq, Debug)]
2964-
#[serde(untagged)]
2965-
enum Data {
2966-
A {
2967-
a: i32,
2968-
#[serde(flatten)]
2969-
flat: Flat,
2970-
},
2971-
}
2972-
2973-
#[derive(Serialize, Deserialize, PartialEq, Debug)]
2974-
struct Flat {
2975-
b: i32,
2976-
}
2977-
2978-
let data = Data::A {
2979-
a: 0,
2980-
flat: Flat { b: 0 },
2981-
};
2982-
2983-
assert_tokens(
2984-
&data,
2985-
&[
2986-
Token::Map { len: None },
2987-
Token::Str("a"),
2988-
Token::I32(0),
2989-
Token::Str("b"),
2990-
Token::I32(0),
2991-
Token::MapEnd,
2992-
],
2993-
);
2994-
}
2995-
29962949
#[derive(Debug, PartialEq, Serialize, Deserialize)]
29972950
struct Flatten {
29982951
#[serde(flatten)]

0 commit comments

Comments
 (0)