// `{{ enum_name }}` is EXTERNALLY tagged in the core crate, so serde writes a unit variant as a
// bare string and a data variant as a single-keyed object whose value IS the payload -- never the
// flat `{"{{ tag_field }}": ...}` object this class stores its state in. A derived impl therefore
// could not read the wire the core type emits, and every value of this type failed to
// deserialize. The flat object form is still accepted so JSON this class previously produced
// keeps round-tripping. ~keep
impl serde::Serialize for {{ enum_name }} {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self.{{ tag_field }}_tag.as_str() {
{{ serialize_arms }} other => serializer.serialize_str(other),
}
}
}
impl<'de> serde::Deserialize<'de> for {{ enum_name }} {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct AlefExternalVisitor;
impl<'de> serde::de::Visitor<'de> for AlefExternalVisitor {
type Value = {{ enum_name }};
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("a string or an object for {{ enum_name }}")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match value {
{{ visit_str_arms }}{{ visit_str_fallback }} }
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let mut entries: Vec<(String, serde_json::Value)> = Vec::new();
while let Some(entry) = map.next_entry::<String, serde_json::Value>()? {
entries.push(entry);
}
if entries.iter().any(|(key, _)| key == "{{ tag_field }}") {
let mut value = {{ enum_name }}::default();
for (key, entry) in entries {
match key.as_str() {
"{{ tag_field }}" => value.{{ tag_field }}_tag = entry.as_str().unwrap_or_default().to_string(),
{{ flat_field_arms }} _ => {}
}
}
return Ok(value);
}
match entries.into_iter().next() {
{{ visit_map_arms }} Some((key, _)) => Err(serde::de::Error::unknown_variant(key.as_str(), &[{{ variant_list }}])),
None => Ok({{ enum_name }}::default()),
}
}
}
deserializer.deserialize_any(AlefExternalVisitor)
}
}