Skip to content

Commit 0944b03

Browse files
committed
Naming, compile-time flag check
* `seq` to `seq_form` rename * now flag is only evaluated at the compile time.
1 parent bc08ad0 commit 0944b03

3 files changed

Lines changed: 54 additions & 20 deletions

File tree

serde/src/private/de.rs

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ use crate::de::{MapAccess, Unexpected};
1212
#[cfg(any(feature = "std", feature = "alloc"))]
1313
pub use self::content::{
1414
Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer,
15-
InternallyTaggedUnitVisitor, TagContentOtherField, TagContentOtherFieldVisitor,
16-
TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor,
15+
InternallyTaggedUnitVisitor, NoSeqTaggedContentVisitor, TagContentOtherField,
16+
TagContentOtherFieldVisitor, TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor,
17+
UntaggedUnitVisitor,
1718
};
1819

1920
pub use crate::seed::InPlaceSeed;
@@ -206,7 +207,6 @@ mod content {
206207
// This issue is tracking making some of this stuff public:
207208
// https://github.com/serde-rs/serde/issues/741
208209

209-
use crate::de::Error;
210210
use crate::lib::*;
211211

212212
use crate::actually_private;
@@ -830,6 +830,40 @@ mod content {
830830
}
831831
}
832832

833+
/// Used by generated code to deserialize an internally tagged enum without sequence format.
834+
///
835+
/// Captures map from the original deserializer and searches
836+
/// a tag in it.
837+
///
838+
/// Not public API.
839+
pub struct NoSeqTaggedContentVisitor<T>(TaggedContentVisitor<T>);
840+
841+
impl<T> NoSeqTaggedContentVisitor<T> {
842+
/// Visitor for the content of an internally tagged enum with the given
843+
/// tag name.
844+
pub fn new(name: &'static str, expecting: &'static str) -> Self {
845+
Self(TaggedContentVisitor::new(name, expecting))
846+
}
847+
}
848+
849+
impl<'de, T> Visitor<'de> for NoSeqTaggedContentVisitor<T>
850+
where
851+
T: Deserialize<'de>,
852+
{
853+
type Value = (T, Content<'de>);
854+
855+
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
856+
self.0.expecting(fmt)
857+
}
858+
859+
fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>
860+
where
861+
M: MapAccess<'de>,
862+
{
863+
self.0.visit_map(map)
864+
}
865+
}
866+
833867
/// Used by generated code to deserialize an internally tagged enum.
834868
///
835869
/// Captures map or sequence from the original deserializer and searches
@@ -840,18 +874,16 @@ mod content {
840874
tag_name: &'static str,
841875
expecting: &'static str,
842876
value: PhantomData<T>,
843-
use_seq: bool,
844877
}
845878

846879
impl<T> TaggedContentVisitor<T> {
847880
/// Visitor for the content of an internally tagged enum with the given
848881
/// tag name.
849-
pub fn new(name: &'static str, expecting: &'static str, use_seq: bool) -> Self {
882+
pub fn new(name: &'static str, expecting: &'static str) -> Self {
850883
TaggedContentVisitor {
851884
tag_name: name,
852885
expecting,
853886
value: PhantomData,
854-
use_seq,
855887
}
856888
}
857889
}
@@ -870,18 +902,14 @@ mod content {
870902
where
871903
S: SeqAccess<'de>,
872904
{
873-
if self.use_seq {
874-
let tag = match tri!(seq.next_element()) {
875-
Some(tag) => tag,
876-
None => {
877-
return Err(de::Error::missing_field(self.tag_name));
878-
}
879-
};
880-
let rest = de::value::SeqAccessDeserializer::new(seq);
881-
Ok((tag, tri!(Content::deserialize(rest))))
882-
} else {
883-
Err(Error::invalid_type(Unexpected::Seq, &self))
884-
}
905+
let tag = match tri!(seq.next_element()) {
906+
Some(tag) => tag,
907+
None => {
908+
return Err(de::Error::missing_field(self.tag_name));
909+
}
910+
};
911+
let rest = de::value::SeqAccessDeserializer::new(seq);
912+
Ok((tag, tri!(Content::deserialize(rest))))
885913
}
886914

887915
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>

serde_derive/src/de.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1409,14 +1409,20 @@ fn deserialize_internally_tagged_enum(
14091409
let expecting = format!("internally tagged enum {}", params.type_name());
14101410
let expecting = cattrs.expecting().unwrap_or(&expecting);
14111411

1412+
let tagged_content_visitor = if use_seq {
1413+
quote!(_serde::__private::de::TaggedContentVisitor)
1414+
} else {
1415+
quote!(_serde::__private::de::NoSeqTaggedContentVisitor)
1416+
};
1417+
14121418
quote_block! {
14131419
#variant_visitor
14141420

14151421
#variants_stmt
14161422

14171423
let (__tag, __content) = _serde::Deserializer::deserialize_any(
14181424
__deserializer,
1419-
_serde::__private::de::TaggedContentVisitor::<__Field>::new(#tag, #expecting, #use_seq))?;
1425+
#tagged_content_visitor::<__Field>::new(#tag, #expecting))?;
14201426
let __deserializer = _serde::__private::de::ContentDeserializer::<__D::Error>::new(__content);
14211427

14221428
match __tag {

serde_derive/src/internals/symbol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub const TAG: Symbol = Symbol("tag");
3737
pub const TRANSPARENT: Symbol = Symbol("transparent");
3838
pub const TRY_FROM: Symbol = Symbol("try_from");
3939
pub const UNTAGGED: Symbol = Symbol("untagged");
40-
pub const USE_SEQ: Symbol = Symbol("seq");
40+
pub const USE_SEQ: Symbol = Symbol("seq_form");
4141
pub const VARIANT_IDENTIFIER: Symbol = Symbol("variant_identifier");
4242
pub const WITH: Symbol = Symbol("with");
4343

0 commit comments

Comments
 (0)