zvariant/as_value/
deserialize.rs1use core::str;
2use std::marker::PhantomData;
3
4use serde::de::{Deserializer, SeqAccess, Visitor};
5
6use crate::{Signature, Type};
7
8pub struct Deserialize<'de, T: Type + serde::Deserialize<'de>>(
24 pub T,
25 std::marker::PhantomData<&'de T>,
26);
27
28impl<'de, T: Type + serde::Deserialize<'de>> serde::Deserialize<'de> for Deserialize<'de, T> {
29 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30 where
31 D: Deserializer<'de>,
32 {
33 if T::SIGNATURE == &Signature::Variant {
37 return Ok(Deserialize(T::deserialize(deserializer)?, PhantomData));
38 }
39
40 const FIELDS: &[&str] = &["signature", "value"];
41 Ok(Deserialize(
42 deserializer.deserialize_struct(
43 "Variant",
44 FIELDS,
45 DeserializeValueVisitor(PhantomData),
46 )?,
47 PhantomData,
48 ))
49 }
50}
51
52struct DeserializeValueVisitor<T>(PhantomData<T>);
53
54impl<'de, T: Type + serde::Deserialize<'de>> Visitor<'de> for DeserializeValueVisitor<T> {
55 type Value = T;
56
57 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 formatter.write_str("Variant")
59 }
60
61 fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
62 where
63 V: SeqAccess<'de>,
64 {
65 let sig: Signature = seq
66 .next_element()?
67 .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
68 if T::SIGNATURE != &sig {
69 return Err(serde::de::Error::invalid_value(
70 serde::de::Unexpected::Str(&sig.to_string()),
71 &"the value signature",
72 ));
73 }
74
75 seq.next_element()?
76 .ok_or_else(|| serde::de::Error::invalid_length(1, &self))
77 }
78}
79
80impl<'de, T: Type + serde::Deserialize<'de>> Type for Deserialize<'de, T> {
81 const SIGNATURE: &'static Signature = &Signature::Variant;
82}
83
84pub fn deserialize<'de, T, D>(deserializer: D) -> std::result::Result<T, D::Error>
86where
87 D: Deserializer<'de>,
88 T: serde::Deserialize<'de> + Type + 'de,
89{
90 use serde::Deserialize as _;
91
92 Deserialize::deserialize(deserializer).map(|v| v.0)
93}
94
95pub fn deserialize_optional<'de, T, D>(deserializer: D) -> std::result::Result<Option<T>, D::Error>
97where
98 D: Deserializer<'de>,
99 T: serde::Deserialize<'de> + Type + 'de,
100{
101 deserialize(deserializer).map(Some)
102}