1use crate::{decode, schema::*, types::Object};
2use serde::de::{
3 self, DeserializeSeed, Deserializer, IntoDeserializer, MapAccess, SeqAccess, Unexpected,
4 Visitor,
5};
6use std::fmt;
7
8struct UnionVisitor<'a>(&'a Union);
9
10macro_rules! find {
11 ($s:expr, $unx:expr, $($kind:tt),*) => {
12 $s.0.variants.iter().find(|s| match s {
13 $(Schema::$kind(_) => true,)*
14 _ => false,
15 })
16 .ok_or_else(|| de::Error::invalid_type($unx, &$s))
17 }
18}
19
20impl<'a, 'de> Visitor<'de> for UnionVisitor<'a> {
21 type Value = Object;
22
23 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
24 let names: Vec<_> = self.0.variants.iter().map(|v| v.name()).collect();
25 write!(f, "any of {:?}", names)
26 }
27
28 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
29 where
30 E: de::Error,
31 {
32 let schema = find!(self, Unexpected::Bool(v), Primitive)?;
33 schema.deserialize(v.into_deserializer())
34 }
35
36 fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
37 where
38 E: de::Error,
39 {
40 self.visit_i64(v as i64)
41 }
42
43 fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
44 where
45 E: de::Error,
46 {
47 self.visit_i64(v as i64)
48 }
49
50 fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
51 where
52 E: de::Error,
53 {
54 self.visit_i64(v as i64)
55 }
56
57 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
58 where
59 E: de::Error,
60 {
61 let schema = find!(self, Unexpected::Signed(v), Primitive)?;
62 schema.deserialize(v.into_deserializer())
63 }
64
65 fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
66 where
67 E: de::Error,
68 {
69 self.visit_u64(v as u64)
70 }
71
72 fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
73 where
74 E: de::Error,
75 {
76 self.visit_u64(v as u64)
77 }
78
79 fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
80 where
81 E: de::Error,
82 {
83 self.visit_u64(v as u64)
84 }
85
86 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
87 where
88 E: de::Error,
89 {
90 let schema = find!(self, Unexpected::Unsigned(v), Primitive)?;
91 schema.deserialize(v.into_deserializer())
92 }
93
94 fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
95 where
96 E: de::Error,
97 {
98 self.visit_f64(v as f64)
99 }
100
101 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
102 where
103 E: de::Error,
104 {
105 let schema = find!(self, Unexpected::Float(v), Primitive)?;
106 schema.deserialize(v.into_deserializer())
107 }
108
109 fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
110 where
111 E: de::Error,
112 {
113 self.visit_borrowed_str(&v.to_string())
114 }
115
116 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
117 where
118 E: de::Error,
119 {
120 self.visit_borrowed_str(v)
121 }
122
123 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
124 where
125 E: de::Error,
126 {
127 let schema = find!(self, Unexpected::Str(v), Primitive)?;
128 schema.deserialize(v.into_deserializer())
129 }
130
131 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
132 where
133 E: de::Error,
134 {
135 self.visit_borrowed_str(&v)
136 }
137
138 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
139 where
140 E: de::Error,
141 {
142 self.visit_borrowed_bytes(v)
143 }
144
145 fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
146 where
147 E: de::Error,
148 {
149 let schema = find!(self, Unexpected::Bytes(v), Primitive)?;
150
151 match schema {
152 Schema::Primitive(Primitive::Bytes) => {
153 decode::primitive::BytesVisitor(false).visit_borrowed_bytes(v)
154 }
155 Schema::Primitive(Primitive::ByteArray) => {
156 decode::primitive::BytesVisitor(true).visit_borrowed_bytes(v)
157 }
158 _ => Err(de::Error::invalid_type(Unexpected::Bytes(v), &self)),
159 }
160 }
161
162 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
163 where
164 E: de::Error,
165 {
166 self.visit_borrowed_bytes(&v)
167 }
168
169 fn visit_none<E>(self) -> Result<Self::Value, E>
170 where
171 E: de::Error,
172 {
173 let schema = find!(self, Unexpected::Option, Optional)?;
174
175 match schema {
176 Schema::Optional(option) => decode::option::OptionVisitor(option).visit_none(),
177 _ => Err(de::Error::invalid_type(Unexpected::Option, &self)),
178 }
179 }
180
181 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
182 where
183 D: Deserializer<'de>,
184 {
185 let schema = find!(self, Unexpected::Option, Optional)?;
186 schema.deserialize(deserializer)
187 }
188
189 fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
190 where
191 A: SeqAccess<'de>,
192 {
193 let schema = find!(self, Unexpected::Seq, List, Tuple, Set)?;
194
195 match schema {
196 Schema::List(l) => decode::list::ListVisitor(l).visit_seq(seq),
197 Schema::Tuple(t) => decode::tuple::TupleVisitor(t).visit_seq(seq),
198 Schema::Set(s) => decode::set::SetVisitor(s).visit_seq(seq),
199 _ => unreachable!(),
200 }
201 }
202
203 fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
204 where
205 A: MapAccess<'de>,
206 {
207 let schema = find!(self, Unexpected::Map, Dict, Class)?;
208
209 match schema {
210 Schema::Dict(d) => decode::dict::DictVisitor(d).visit_map(map),
211 Schema::Class(c) => decode::class::ClassVisitor(c).visit_map(map),
212 _ => unreachable!(),
213 }
214 }
215}
216
217impl<'a, 'de> DeserializeSeed<'de> for &'a Union {
218 type Value = Object;
219
220 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
221 where
222 D: Deserializer<'de>,
223 {
224 deserializer.deserialize_any(UnionVisitor(self))
225 }
226}