saya_types/contract/
preference_serde.rs1use serde::Deserialize;
13
14use crate::contract::preference::{DateGrain, OutputStyle, PreferenceValue};
15
16impl<'de> Deserialize<'de> for PreferenceValue {
17 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
18 where
19 D: serde::Deserializer<'de>,
20 {
21 #[derive(Deserialize)]
22 #[serde(field_identifier, rename_all = "snake_case")]
23 enum Field {
24 Kind,
25 Value,
26 Grain,
27 Style,
28 Name,
29 }
30
31 struct PreferenceValueVisitor;
32
33 impl<'de> serde::de::Visitor<'de> for PreferenceValueVisitor {
34 type Value = PreferenceValue;
35
36 fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 f.write_str("a preference value tagged with `kind`")
38 }
39
40 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
41 where
42 A: serde::de::MapAccess<'de>,
43 {
44 let mut kind: Option<String> = None;
45 let mut value: Option<String> = None;
46 let mut grain: Option<DateGrain> = None;
47 let mut style: Option<OutputStyle> = None;
48 let mut name: Option<String> = None;
49 while let Some(key) = map.next_key::<Field>()? {
50 match key {
51 Field::Kind => {
52 if kind.is_some() {
53 return Err(serde::de::Error::duplicate_field("kind"));
54 }
55 kind = Some(map.next_value()?);
56 }
57 Field::Value => {
58 if value.is_some() {
59 return Err(serde::de::Error::duplicate_field("value"));
60 }
61 value = Some(map.next_value()?);
62 }
63 Field::Grain => {
64 if grain.is_some() {
65 return Err(serde::de::Error::duplicate_field("grain"));
66 }
67 grain = Some(map.next_value()?);
68 }
69 Field::Style => {
70 if style.is_some() {
71 return Err(serde::de::Error::duplicate_field("style"));
72 }
73 style = Some(map.next_value()?);
74 }
75 Field::Name => {
76 if name.is_some() {
77 return Err(serde::de::Error::duplicate_field("name"));
78 }
79 name = Some(map.next_value()?);
80 }
81 }
82 }
83 let kind = kind.ok_or_else(|| serde::de::Error::missing_field("kind"))?;
84 match kind.as_str() {
88 "timezone" => {
89 let v = value.ok_or_else(|| serde::de::Error::missing_field("value"))?;
90 PreferenceValue::timezone(v).map_err(serde::de::Error::custom)
91 }
92 "date_grain" => {
93 let g = grain.ok_or_else(|| serde::de::Error::missing_field("grain"))?;
94 Ok(PreferenceValue::date_grain(g))
95 }
96 "output_style" => {
97 let s = style.ok_or_else(|| serde::de::Error::missing_field("style"))?;
98 Ok(PreferenceValue::output_style(s))
99 }
100 "default_profile" => {
101 let n = name.ok_or_else(|| serde::de::Error::missing_field("name"))?;
102 PreferenceValue::default_profile(n).map_err(serde::de::Error::custom)
103 }
104 other => Err(serde::de::Error::unknown_variant(
105 other,
106 &["timezone", "date_grain", "output_style", "default_profile"],
107 )),
108 }
109 }
110 }
111
112 deserializer.deserialize_map(PreferenceValueVisitor)
113 }
114}