alef 0.103.8

Opinionated polyglot binding generator for Rust libraries
Documentation

// `{{ 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)
    }
}