Skip to main content

step_p21/ast/de/
name.rs

1use crate::{ast::*, error::*};
2use serde::de::{self, IntoDeserializer};
3
4// Note for understanding serde enum types
5// ----------------------------------------
6//
7// In serde impl, we have to implement `VariantAccess` and `EnumAccess`
8// since `Visitor::visit_enum` requires `EnumAccess` and it requires
9// `VariantAccess`. `VariantAccess` and `EnumAccess` traits are used for 4 data
10// models:
11//
12// - "unit_variant"    e.g. the `E::A` and `E::B` in `enum E { A, B }`
13// - "newtype_variant" e.g. the `E::N` in `enum E { N(u8) }`
14// - "tuple_variant"   e.g. the `E::T` in `enum E { T(u8, u8) }`
15// - "struct_variant"  e.g. the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`
16//
17// Roughly, `EnumAccess` determines which variant are used e.g. `E::N` in above
18// "newtype_variant" case, and `VariantAccess` determines its component e.g.
19// `1u8`. These are composed into `E::N(1u8)` in `Visitor::visit_enum`.
20//
21impl<'de> de::EnumAccess<'de> for &Name {
22    type Error = crate::error::Error;
23    type Variant = Self;
24
25    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
26    where
27        V: de::DeserializeSeed<'de>,
28    {
29        let key: de::value::StrDeserializer<Self::Error> = match self {
30            Name::Entity(_) => "Entity",
31            Name::Value(_) => "Value",
32            Name::ConstantEntity(_) => "ConstantEntity",
33            Name::ConstantValue(_) => "ConstantValue",
34        }
35        .into_deserializer();
36        let key: V::Value = seed.deserialize(key)?;
37        Ok((key, self))
38    }
39}
40
41impl<'de> de::VariantAccess<'de> for &Name {
42    type Error = crate::error::Error;
43
44    fn unit_variant(self) -> Result<()> {
45        let unexp = de::Unexpected::NewtypeVariant;
46        Err(de::Error::invalid_type(unexp, &"unit variant"))
47    }
48
49    fn newtype_variant_seed<D>(self, seed: D) -> Result<D::Value>
50    where
51        D: de::DeserializeSeed<'de>,
52    {
53        match self {
54            Name::Entity(id) | Name::Value(id) => {
55                seed.deserialize(id.into_deserializer())
56            }
57            Name::ConstantEntity(name) | Name::ConstantValue(name) => {
58                seed.deserialize(name.as_str().into_deserializer())
59            }
60        }
61    }
62
63    fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
64    where
65        V: de::Visitor<'de>,
66    {
67        let unexp = de::Unexpected::NewtypeVariant;
68        Err(de::Error::invalid_type(unexp, &"tuple variant"))
69    }
70
71    fn struct_variant<V>(
72        self,
73        _fields: &'static [&'static str],
74        _visitor: V,
75    ) -> Result<V::Value>
76    where
77        V: de::Visitor<'de>,
78    {
79        let unexp = de::Unexpected::NewtypeVariant;
80        Err(de::Error::invalid_type(unexp, &"struct variant"))
81    }
82}