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