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