perde_core/decode/
class.rs1use crate::{
2 error::{Convert, Result},
3 schema::*,
4 types::{self, Object},
5};
6use serde::de::{self, DeserializeSeed, Deserializer, IgnoredAny, MapAccess, Visitor};
7use std::{borrow::Cow, collections::HashMap, fmt};
8
9pub struct ClassVisitor<'a>(pub &'a Class);
10
11impl<'a, 'de> Visitor<'de> for ClassVisitor<'a> {
12 type Value = Object;
13
14 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
15 write!(f, "a class")
16 }
17
18 fn visit_map<M>(self, mut access: M) -> std::result::Result<Self::Value, M::Error>
19 where
20 M: MapAccess<'de>,
21 {
22 if self.0.flatten_fields.is_empty() {
23 let mut tuple = types::Tuple::new(self.0.fields.len()).de()?;
24 let mut setcount = 0;
25
26 while let Some(key) = access.next_key()? {
27 let key: Cow<str> = key;
28
29 if let Some(s) = self.0.field(&key).de()? {
30 let value: Object = access.next_value_seed(&s.schema)?;
31
32 tuple.set(s.pos, value);
33 setcount += 1;
34 } else {
35 let _: IgnoredAny = access.next_value()?;
36 }
37 }
38
39 if setcount != self.0.num_fields() {
40 return Err(de::Error::custom("missing field"));
41 }
42
43 self.0.ty.construct(tuple).de()
44 } else {
45 let mut map = HashMap::new();
46
47 while let Some(key) = access.next_key()? {
48 let key: Cow<str> = key;
49
50 if let Some(s) = self.0.field(&key).de()? {
51 let value: Object = access.next_value_seed(&s.schema)?;
52
53 map.insert(key, value);
54 } else {
55 let _: IgnoredAny = access.next_value()?;
56 }
57 }
58
59 let cls = self.0.call(&mut map).de()?;
60
61 if !map.is_empty() && self.0.attr.deny_unknown_fields {
62 }
64
65 Ok(cls)
66 }
67 }
68}
69
70impl<'a, 'de> DeserializeSeed<'de> for &'a Class {
71 type Value = Object;
72
73 fn deserialize<D>(self, deserializer: D) -> std::result::Result<Self::Value, D::Error>
74 where
75 D: Deserializer<'de>,
76 {
77 deserializer.deserialize_map(ClassVisitor(self))
78 }
79}
80
81impl Class {
82 pub fn num_fields(&self) -> usize {
83 if self.flatten_fields.is_empty() {
84 self.fields.len()
85 } else {
86 self.flatten_fields.len()
87 }
88 }
89
90 pub fn field(&self, name: &str) -> Result<Option<&FieldSchema>> {
91 let map = if self.flatten_fields.is_empty() {
92 &self.fields
93 } else {
94 &self.flatten_fields
95 };
96
97 map.get(name)
98 .map(|v| {
99 if v.attr.skip || v.attr.skip_deserializing {
100 Ok(None)
101 } else {
102 Ok(Some(v))
103 }
104 })
105 .unwrap_or_else(|| {
106 if self.attr.deny_unknown_fields {
107 Err(err!("the field `{}` is missing", name,))
108 } else {
109 Ok(None)
110 }
111 })
112 }
113
114 pub fn call(&self, map: &mut HashMap<Cow<str>, Object>) -> Result<Object> {
115 let args: Result<Vec<_>> = self
116 .fields
117 .iter()
118 .map(|(k, s)| {
119 if s.attr.flatten {
120 match &s.schema {
121 Schema::Class(cls) => return cls.call(map),
122 Schema::Dict(_) => {
123 let map = std::mem::replace(map, HashMap::new());
124
125 let mut dict = types::Dict::new()?;
126 for (k, v) in map {
127 dict.set(Object::new_str(&k)?, v)?;
128 }
129 return Ok(dict.into_inner());
130 }
131 _ => return Err(err!("found `flatten` attribute an non-map type",)),
132 }
133 }
134
135 let k: &str = k.as_ref();
136 match map.remove(k) {
137 Some(v) => Ok(v),
138 None => {
139 if self.attr.default
140 || s.attr.default.is_some()
141 || s.attr.skip
142 || s.attr.skip_deserializing
143 {
144 if let Some(d) = s.attr.default.as_ref() {
145 return Ok(d.clone());
146 } else if let Some(d) = s.attr.default_factory.as_ref() {
147 return d.call_noarg();
148 }
149 }
150 Err(err!("missing field \"{}\"", k))
151 }
152 }
153 })
154 .collect();
155
156 self.construct(args?)
157 }
158
159 pub fn construct(&self, args: Vec<Object>) -> Result<Object> {
160 let mut tuple = types::Tuple::new(args.len())?;
161 for (i, arg) in args.into_iter().enumerate() {
162 tuple.set(i, arg);
163 }
164 self.ty.construct(tuple)
165 }
166}