1use std::borrow::Cow;
3use std::marker::PhantomData;
4
5use deser_core::adapters::Same;
6use deser_core::de::{OwnedSink, Sink, SinkHandle, checked_update};
7use deser_core::ser::{Describe, Emit};
8use deser_core::{Atom, ContainerShape, Deserialize, Error, Serialize, State};
9
10use crate::{Validator, Violation};
11
12pub struct Check<V, A = Same>(PhantomData<fn() -> (V, A)>);
99
100impl<'de, T, V, A> Deserialize<'de, T> for Check<V, A>
101where
102 T: Send,
103 V: Validator<T> + 'static,
104 A: Deserialize<'de, T>,
105{
106 fn deserialize_into<'out>(
107 out: &'out mut Option<T>,
108 state: &mut State,
109 ) -> SinkHandle<'out, 'de> {
110 SinkHandle::arena(
111 CheckSink::<T, V> {
112 out,
113 sink: OwnedSink::deserialize_as::<A>(state),
114 start: None,
115 _validator: PhantomData,
116 },
117 state,
118 )
119 }
120
121 fn expecting() -> Cow<'static, str> {
122 A::expecting()
123 }
124
125 fn describe_type(d: &mut dyn Describe) {
126 A::describe_type(d)
127 }
128
129 fn initial_value() -> Option<T> {
130 A::initial_value().filter(|value| V::validate(value).is_ok())
131 }
132
133 fn deserialize_update<'out>(value: &'out mut T, state: &mut State) -> SinkHandle<'out, 'de> {
136 checked_update(
137 value,
138 A::deserialize_update,
139 |value| V::validate(value).map_err(Violation::into_error),
140 state,
141 )
142 }
143
144 #[inline]
145 fn __private_atom_into(
146 out: &mut Option<T>,
147 atom: Atom,
148 state: &mut State,
149 ) -> Result<(), Error> {
150 A::__private_atom_into(out, atom, state)?;
151 validate_slot::<T, V>(out)
152 }
153
154 #[inline]
155 fn __private_borrowed_atom_into(
156 out: &mut Option<T>,
157 atom: Atom<'de>,
158 state: &mut State,
159 ) -> Result<(), Error> {
160 A::__private_borrowed_atom_into(out, atom, state)?;
161 validate_slot::<T, V>(out)
162 }
163}
164
165fn validate_slot<T, V: Validator<T>>(slot: &mut Option<T>) -> Result<(), Error> {
169 if let Some(ref value) = *slot
170 && let Err(violation) = V::validate(value)
171 {
172 *slot = None;
173 return Err(violation.into_error());
174 }
175 Ok(())
176}
177
178impl<T: ?Sized, V: 'static, A: Serialize<T>> Serialize<T> for Check<V, A> {
179 fn serialize<'a>(value: &'a T, state: &mut State) -> Result<Emit<'a>, Error> {
180 A::serialize(value, state)
181 }
182
183 fn finish(value: &T, state: &mut State) -> Result<(), Error> {
184 A::finish(value, state)
185 }
186
187 fn is_optional(value: &T) -> bool {
188 A::is_optional(value)
189 }
190
191 fn container_shape(value: &T) -> ContainerShape {
192 A::container_shape(value)
193 }
194
195 fn describe(value: &T, d: &mut dyn Describe) {
196 A::describe(value, d)
197 }
198}
199
200struct CheckSink<'a, 'de, T, V> {
205 out: &'a mut Option<T>,
206 sink: OwnedSink<'de, T>,
207 start: Option<usize>,
209 _validator: PhantomData<fn() -> V>,
210}
211
212impl<'a, 'de, T, V> CheckSink<'a, 'de, T, V> {
213 fn begin(&mut self, state: &State) -> &mut (dyn Sink<'de> + '_) {
214 self.start = state.input_range().map(|range| range.start);
215 self.sink.get_mut()
216 }
217}
218
219impl<'a, 'de, T: Send, V: Validator<T>> Sink<'de> for CheckSink<'a, 'de, T, V> {
220 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
221 self.begin(state).atom(atom, state)
222 }
223
224 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
225 self.begin(state).borrowed_atom(atom, state)
226 }
227
228 fn map(&mut self, state: &mut State) -> Result<(), Error> {
229 self.begin(state).map(state)
230 }
231
232 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
233 self.begin(state).seq(state)
234 }
235
236 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
237 self.sink.get_mut().next_key(state)
238 }
239
240 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
241 self.sink.get_mut().next_value(state)
242 }
243
244 fn __private_key_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
245 self.sink.get_mut().__private_key_atom(atom, state)
246 }
247
248 fn __private_value_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
249 self.sink.get_mut().__private_value_atom(atom, state)
250 }
251
252 fn __private_borrowed_key_atom(
253 &mut self,
254 atom: Atom<'de>,
255 state: &mut State,
256 ) -> Result<(), Error> {
257 self.sink.get_mut().__private_borrowed_key_atom(atom, state)
258 }
259
260 fn __private_borrowed_value_atom(
261 &mut self,
262 atom: Atom<'de>,
263 state: &mut State,
264 ) -> Result<(), Error> {
265 self.sink
266 .get_mut()
267 .__private_borrowed_value_atom(atom, state)
268 }
269
270 fn value_for_key(
271 &mut self,
272 key: &str,
273 state: &mut State,
274 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
275 self.sink.get_mut().value_for_key(key, state)
276 }
277
278 fn recover(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
279 self.sink.get_mut().recover(err, state)
280 }
281
282 fn finish(&mut self, state: &mut State) -> Result<(), Error> {
283 self.sink.get_mut().finish(state)?;
284 if let Some(value) = self.sink.take() {
285 if let Err(violation) = V::validate(&value) {
286 let mut err = violation.into_error();
287 if let Some(start) = self.start {
288 err.set_offset(start);
289 }
290 return Err(err);
291 }
292 *self.out = Some(value);
293 }
294 Ok(())
295 }
296
297 fn expecting(&self) -> Cow<'_, str> {
298 self.sink.get().expecting()
299 }
300}