1use de::seed::SeedFactory;
14use util::de::content::{Content, ContentDeserializer};
15
16use std;
17use std::marker::PhantomData;
18
19use serde;
20
21
22pub fn deserialize<'de, 'k, T, K, Kc: ?Sized, D, F>(
42 deserializer: D,
43 tag_key: &'k Kc,
44 value_key: &'k Kc,
45 seed_factory: F,
46) -> Result<F::Value, D::Error>
47where
48 T: serde::Deserialize<'de>,
49 D: serde::Deserializer<'de>,
50 F: SeedFactory<'de, T>,
51 K: serde::Deserialize<'de>,
52 K: std::cmp::PartialEq<&'k Kc>,
53{
54 deserialize_seed::<K, _, _, _, _>(
55 deserializer,
56 tag_key,
57 value_key,
58 seed_factory,
59 PhantomData::<T>,
60 )
61}
62
63
64pub fn deserialize_seed<'de, 'k, K, Kc: ?Sized, D, F, S>(
79 deserializer: D,
80 tag_key: &'k Kc,
81 value_key: &'k Kc,
82 seed_factory: F,
83 tag_seed: S,
84) -> Result<F::Value, D::Error>
85where
86 D: serde::Deserializer<'de>,
87 F: SeedFactory<'de, S::Value>,
88 S: serde::de::DeserializeSeed<'de>,
89 K: serde::Deserialize<'de>,
90 K: std::cmp::PartialEq<&'k Kc>,
91{
92 deserializer.deserialize_map(Visitor::<K, _, _, _>::new(
93 tag_key,
94 value_key,
95 seed_factory,
96 tag_seed,
97 ))
98}
99
100
101pub struct Visitor<'a, K, Kc: ?Sized + 'a, F, S> {
122 seed_factory: F,
123 tag_seed: S,
124 tag_key: &'a Kc,
125 value_key: &'a Kc,
126 _phantom_k: PhantomData<K>,
127}
128
129impl<'a, K, Kc: ?Sized, F, S> Visitor<'a, K, Kc, F, S> {
130 pub fn new(tag_key: &'a Kc, value_key: &'a Kc, seed_factory: F, tag_seed: S) -> Self {
133 Visitor {
134 seed_factory,
135 tag_seed,
136 tag_key,
137 value_key,
138 _phantom_k: PhantomData,
139 }
140 }
141}
142
143impl<'de, 'a, K, Kc: ?Sized, F, S> serde::de::Visitor<'de> for Visitor<'a, K, Kc, F, S>
144where
145 K: serde::Deserialize<'de>,
146 K: std::cmp::PartialEq<&'a Kc>,
147 F: SeedFactory<'de, S::Value>,
148 S: serde::de::DeserializeSeed<'de>,
149{
150 type Value = F::Value;
151
152 fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
153 write!(fmt, "a map with exactly two entries")
154 }
155
156 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
157 where
158 A: serde::de::MapAccess<'de>,
159 {
160 use serde::de::DeserializeSeed;
161 use serde::de::Error;
162
163 match map.size_hint() {
165 Some(n) if n != 2 => Err(Error::invalid_length(n, &self))?,
166 _ => {},
167 }
168
169 let key_1 = map.next_key_seed(KeySeed::<_, K>::new(self.tag_key, self.value_key))?
170 .ok_or_else(|| Error::invalid_length(0, &self))?;
171
172 if key_1 == Key::Tag {
174 let tag = map.next_value_seed(self.tag_seed)?;
175
176 let value_key = map.next_key_seed(KeySeed::<_, K>::new(self.tag_key, self.value_key))?
177 .ok_or_else(|| Error::invalid_length(1, &"a map with exactly two entries"))?;
178
179 if value_key == Key::Value {
180 map.next_value_seed(self.seed_factory.seed(tag)?)
181 } else {
182 Err(Error::custom("duplicate tag-key"))
183 }
184
185 } else {
187 let value: Content = map.next_value()?;
188
189 let tag_key = map.next_key_seed(KeySeed::<_, K>::new(self.tag_key, self.value_key))?
190 .ok_or_else(|| Error::invalid_length(1, &self))?;
191
192 let tag = if tag_key == Key::Tag {
193 map.next_value_seed(self.tag_seed)
194 } else {
195 Err(Error::custom("duplicate value-key"))
196 }?;
197
198 let de = ContentDeserializer::new(value);
199 self.seed_factory.seed(tag)?.deserialize(de)
200 }
201 }
202}
203
204
205pub fn deserialize_known<'de, 'a, T, V, K, Kc: ?Sized, D>(
225 deserializer: D,
226 tag_key: &'a Kc,
227 value_key: &'a Kc,
228) -> Result<(T, V), D::Error>
229where
230 T: serde::Deserialize<'de>,
231 V: serde::Deserialize<'de>,
232 D: serde::Deserializer<'de>,
233 K: serde::Deserialize<'de>,
234 K: std::cmp::PartialEq<&'a Kc>,
235{
236 deserialize_known_seed::<K, _, _, _, _>(
237 deserializer,
238 tag_key,
239 value_key,
240 PhantomData::<T>,
241 PhantomData::<V>,
242 )
243}
244
245
246pub fn deserialize_known_seed<'de, 'a, K, Kc: ?Sized, D, T, V>(
261 deserializer: D,
262 tag_key: &'a Kc,
263 value_key: &'a Kc,
264 tag_seed: T,
265 value_seed: V,
266) -> Result<(T::Value, V::Value), D::Error>
267where
268 T: serde::de::DeserializeSeed<'de>,
269 V: serde::de::DeserializeSeed<'de>,
270 D: serde::Deserializer<'de>,
271 K: serde::Deserialize<'de>,
272 K: std::cmp::PartialEq<&'a Kc>,
273{
274 deserializer.deserialize_map(KnownVisitor::<K, _, _, _>::new(
275 tag_seed,
276 value_seed,
277 tag_key,
278 value_key,
279 ))
280}
281
282
283pub struct KnownVisitor<'a, K, Kc: ?Sized + 'a, T, V> {
301 tag_seed: T,
302 value_seed: V,
303 tag_key: &'a Kc,
304 value_key: &'a Kc,
305 _phantom_k: PhantomData<K>,
306}
307
308impl<'a, K, Kc: ?Sized, T, V> KnownVisitor<'a, K, Kc, T, V> {
309 pub fn new(tag_seed: T, value_seed: V, tag_key: &'a Kc, value_key: &'a Kc) -> Self {
311 KnownVisitor {
312 tag_seed,
313 value_seed,
314 tag_key,
315 value_key,
316 _phantom_k: PhantomData,
317 }
318 }
319}
320
321impl<'de, 'a, K, Kc: ?Sized, T, V> serde::de::Visitor<'de> for KnownVisitor<'a, K, Kc, T, V>
322where
323 T: serde::de::DeserializeSeed<'de>,
324 V: serde::de::DeserializeSeed<'de>,
325 K: serde::Deserialize<'de>,
326 K: std::cmp::PartialEq<&'a Kc>,
327{
328 type Value = (T::Value, V::Value);
329
330 fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
331 write!(fmt, "a map with exactly two entries")
332 }
333
334 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
335 where
336 A: serde::de::MapAccess<'de>,
337 {
338 use serde::de::Error;
339
340 match map.size_hint() {
342 Some(n) if n != 2 => Err(Error::invalid_length(n, &self))?,
343 _ => {},
344 }
345
346 let key_1 = map.next_key_seed(KeySeed::<_, K>::new(self.tag_key, self.value_key))?
347 .ok_or_else(|| Error::invalid_length(0, &self))?;
348
349 if key_1 == Key::Tag {
350 let tag = map.next_value_seed(self.tag_seed)?;
351
352 let value_key = map.next_key_seed(KeySeed::<_, K>::new(self.tag_key, self.value_key))?
353 .ok_or_else(|| Error::invalid_length(1, &"a map with exactly two entries"))?;
354
355 if value_key == Key::Value {
356 Ok((tag, map.next_value_seed(self.value_seed)?))
357 } else {
358 Err(Error::custom("duplicate tag-key"))
359 }
360 } else {
361 let value = map.next_value_seed(self.value_seed)?;
362
363 let tag_key = map.next_key_seed(KeySeed::<_, K>::new(self.tag_key, self.value_key))?
364 .ok_or_else(|| Error::invalid_length(1, &"a map with exactly two entries"))?;
365
366 if tag_key == Key::Tag {
367 Ok((map.next_value_seed(self.tag_seed)?, value))
368 } else {
369 Err(Error::custom("duplicate value-key"))
370 }
371 }
372 }
373}
374
375
376#[derive(PartialEq)]
377enum Key {
378 Tag,
379 Value,
380}
381
382
383struct KeySeed<'a, Kc: ?Sized + 'a, Kd> {
384 tag_key: &'a Kc,
385 value_key: &'a Kc,
386 _phantom_kd: std::marker::PhantomData<Kd>,
387}
388
389impl<'a, Kc: ?Sized, Kd> KeySeed<'a, Kc, Kd> {
390 fn new(tag_key: &'a Kc, value_key: &'a Kc) -> Self {
391 KeySeed {
392 tag_key: tag_key,
393 value_key: value_key,
394 _phantom_kd: std::marker::PhantomData,
395 }
396 }
397}
398
399impl<'de, 'a, Kc: ?Sized, Kd> serde::de::DeserializeSeed<'de> for KeySeed<'a, Kc, Kd>
400where
401 Kd: serde::de::Deserialize<'de>,
402 Kd: std::cmp::PartialEq<&'a Kc>,
403{
404 type Value = Key;
405
406 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
407 where
408 D: serde::Deserializer<'de>,
409 {
410 let key = Kd::deserialize(deserializer)?;
411
412 if key == self.tag_key {
413 Ok(Key::Tag)
414 } else if key == self.value_key {
415 Ok(Key::Value)
416 } else {
417 Err(serde::de::Error::custom(
418 "invalid entry key, expected either the specified tag- or value-key",
419 ))
420 }
421 }
422}