Skip to content

Commit 2dddc77

Browse files
committed
Cover ContentRefDeserializer::deserialize_option
1 parent 8514f41 commit 2dddc77

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

serde/src/private/de.rs

Lines changed: 7 additions & 0 deletions
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
}

test_suite/tests/test_enum_untagged.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,80 @@ fn newtype_enum() {
191191
);
192192
}
193193

194+
// Reaches crate::private::de::content::ContentRefDeserializer::deserialize_option
195+
mod with_optional_field {
196+
use super::*;
197+
198+
#[derive(Debug, PartialEq, Serialize, Deserialize)]
199+
#[serde(untagged)]
200+
enum Enum {
201+
Struct { optional: Option<u32> },
202+
Null,
203+
}
204+
205+
#[test]
206+
fn some() {
207+
assert_tokens(
208+
&Enum::Struct { optional: Some(42) },
209+
&[
210+
Token::Struct {
211+
name: "Enum",
212+
len: 1,
213+
},
214+
Token::Str("optional"),
215+
Token::Some,
216+
Token::U32(42),
217+
Token::StructEnd,
218+
],
219+
);
220+
}
221+
222+
#[test]
223+
fn some_without_marker() {
224+
assert_de_tokens(
225+
&Enum::Struct { optional: Some(42) },
226+
&[
227+
Token::Struct {
228+
name: "Enum",
229+
len: 1,
230+
},
231+
Token::Str("optional"),
232+
Token::U32(42),
233+
Token::StructEnd,
234+
],
235+
);
236+
}
237+
238+
#[test]
239+
fn none() {
240+
assert_tokens(
241+
&Enum::Struct { optional: None },
242+
&[
243+
Token::Struct {
244+
name: "Enum",
245+
len: 1,
246+
},
247+
Token::Str("optional"),
248+
Token::None,
249+
Token::StructEnd,
250+
],
251+
);
252+
}
253+
254+
#[test]
255+
fn unit() {
256+
assert_de_tokens(
257+
&Enum::Struct { optional: None },
258+
&[
259+
Token::Map { len: None },
260+
Token::Str("optional"),
261+
Token::Unit,
262+
Token::MapEnd,
263+
],
264+
);
265+
}
266+
}
267+
194268
#[test]
195269
fn string_and_bytes() {
196270
#[derive(Debug, PartialEq, Deserialize)]

0 commit comments

Comments
 (0)