1use super::{
2 DeserializeContent, DeserializeHelper, Expected, IdentifiedValue, Identifier, IdentifierDeserializer, IdentifierFor,
3 MapAccessValueDeserializer, SerdePathToken, TrackedError, Tracker, TrackerDeserializeIdentifier, TrackerDeserializer,
4 TrackerFor, TrackerWrapper, report_tracked_error, set_irrecoverable,
5};
6
7pub trait TrackedStructDeserializer<'de>: Sized + TrackerFor + IdentifierFor + Expected
8where
9 Self::Tracker: TrackerWrapper,
10{
11 const DENY_UNKNOWN_FIELDS: bool = false;
12
13 fn deserialize<D>(
14 &mut self,
15 field: Self::Identifier,
16 tracker: &mut <Self::Tracker as TrackerWrapper>::Tracker,
17 deserializer: D,
18 ) -> Result<(), D::Error>
19 where
20 D: DeserializeContent<'de>;
21}
22
23impl<'de, T> TrackedStructDeserializer<'de> for Box<T>
24where
25 T: TrackedStructDeserializer<'de> + Default,
26 T::Tracker: Tracker<Target = T> + Default + TrackerWrapper,
27{
28 const DENY_UNKNOWN_FIELDS: bool = T::DENY_UNKNOWN_FIELDS;
29
30 #[inline(always)]
31 fn deserialize<D>(
32 &mut self,
33 field: Self::Identifier,
34 tracker: &mut <Self::Tracker as TrackerWrapper>::Tracker,
35 deserializer: D,
36 ) -> Result<(), D::Error>
37 where
38 D: DeserializeContent<'de>,
39 {
40 T::deserialize(self.as_mut(), field, tracker, deserializer)
41 }
42}
43
44#[derive(Debug, Default)]
45pub struct StructTracker<T>(pub T);
46
47impl<T: Tracker> TrackerWrapper for StructTracker<T> {
48 type Tracker = T;
49}
50
51impl<T> std::ops::Deref for StructTracker<T> {
52 type Target = T;
53
54 fn deref(&self) -> &Self::Target {
55 &self.0
56 }
57}
58
59impl<T> std::ops::DerefMut for StructTracker<T> {
60 fn deref_mut(&mut self) -> &mut Self::Target {
61 &mut self.0
62 }
63}
64
65impl<T> Tracker for StructTracker<T>
66where
67 T: Tracker,
68{
69 type Target = T::Target;
70
71 fn allow_duplicates(&self) -> bool {
72 self.0.allow_duplicates()
73 }
74}
75
76impl<'de, T, S> serde::de::DeserializeSeed<'de> for DeserializeHelper<'_, StructTracker<T>>
77where
78 T: Tracker<Target = S>,
79 S: TrackedStructDeserializer<'de, Tracker = StructTracker<T>>,
80{
81 type Value = ();
82
83 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
84 where
85 D: serde::Deserializer<'de>,
86 {
87 deserializer.deserialize_struct(S::NAME, <S::Identifier as Identifier>::OPTIONS, self)
88 }
89}
90
91impl<'de, T, S> TrackerDeserializer<'de> for StructTracker<T>
92where
93 T: Tracker<Target = S>,
94 S: TrackedStructDeserializer<'de, Tracker = StructTracker<T>>,
95{
96 fn deserialize<D>(&mut self, value: &mut Self::Target, deserializer: D) -> Result<(), D::Error>
97 where
98 D: DeserializeContent<'de>,
99 {
100 deserializer.deserialize_seed(DeserializeHelper { tracker: self, value })
101 }
102}
103
104impl<'de, T, S> serde::de::Visitor<'de> for DeserializeHelper<'_, StructTracker<T>>
105where
106 T: Tracker<Target = S>,
107 S: TrackedStructDeserializer<'de, Tracker = StructTracker<T>>,
108{
109 type Value = ();
110
111 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
112 S::expecting(formatter)
113 }
114
115 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
116 where
117 A: serde::de::MapAccess<'de>,
118 {
119 while let Some(key) = map
120 .next_key_seed(IdentifierDeserializer::<S::Identifier>::default())
121 .inspect_err(|_| {
122 set_irrecoverable();
123 })?
124 {
125 let mut deserialized = false;
126 match key {
127 IdentifiedValue::Found(field) => {
128 let _token = SerdePathToken::push_field(field.name());
129 S::deserialize(
130 self.value,
131 field,
132 self.tracker,
133 MapAccessValueDeserializer {
134 map: &mut map,
135 deserialized: &mut deserialized,
136 },
137 )?;
138 }
139 IdentifiedValue::Unknown(field) => {
140 let _token = SerdePathToken::push_field(&field);
141 report_tracked_error(TrackedError::unknown_field(S::DENY_UNKNOWN_FIELDS))?;
142 }
143 }
144
145 if !deserialized {
146 map.next_value::<serde::de::IgnoredAny>().inspect_err(|_| {
147 set_irrecoverable();
148 })?;
149 }
150 }
151
152 Ok(())
153 }
154}
155
156impl<'de, T> TrackerDeserializeIdentifier<'de> for StructTracker<T>
157where
158 T: Tracker,
159 T::Target: IdentifierFor + TrackedStructDeserializer<'de, Tracker = Self>,
160{
161 fn deserialize<D>(
162 &mut self,
163 value: &mut Self::Target,
164 identifier: <Self::Target as IdentifierFor>::Identifier,
165 deserializer: D,
166 ) -> Result<(), D::Error>
167 where
168 D: DeserializeContent<'de>,
169 {
170 T::Target::deserialize(value, identifier, self, deserializer)
171 }
172}