1use std::borrow::Cow;
3use std::marker::PhantomData;
4
5use deser_core::adapters::{DeserializeAs, Same, SerializeAs};
6use deser_core::de::{OwnedSink, Sink, SinkHandle, checked_update};
7use deser_core::ser::{Chunk, Describe};
8use deser_core::{Atom, ContainerShape, Error, State};
9
10use crate::{Validator, Violation};
11
12pub struct Check<V, A = Same>(PhantomData<fn() -> (V, A)>);
99
100impl<'de, T, V, A> DeserializeAs<'de, T> for Check<V, A>
101where
102 T: Send,
103 V: Validator<T> + 'static,
104 A: DeserializeAs<'de, T>,
105{
106 fn deserialize_into_as<'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 initial_value_as() -> Option<T> {
122 A::initial_value_as().filter(|value| V::validate(value).is_ok())
123 }
124
125 fn deserialize_update_as<'out>(value: &'out mut T, state: &mut State) -> SinkHandle<'out, 'de>
128 where
129 T: Send,
130 {
131 checked_update(
132 value,
133 A::deserialize_update_as,
134 |value| V::validate(value).map_err(Violation::into_error),
135 state,
136 )
137 }
138
139 #[inline]
140 fn __private_atom_into_as(
141 out: &mut Option<T>,
142 atom: Atom,
143 state: &mut State,
144 ) -> Result<(), Error> {
145 A::__private_atom_into_as(out, atom, state)?;
146 validate_slot::<T, V>(out)
147 }
148
149 #[inline]
150 fn __private_borrowed_atom_into_as(
151 out: &mut Option<T>,
152 atom: Atom<'de>,
153 state: &mut State,
154 ) -> Result<(), Error> {
155 A::__private_borrowed_atom_into_as(out, atom, state)?;
156 validate_slot::<T, V>(out)
157 }
158}
159
160fn validate_slot<T, V: Validator<T>>(slot: &mut Option<T>) -> Result<(), Error> {
164 if let Some(ref value) = *slot
165 && let Err(violation) = V::validate(value)
166 {
167 *slot = None;
168 return Err(violation.into_error());
169 }
170 Ok(())
171}
172
173impl<T: ?Sized, V: 'static, A: SerializeAs<T>> SerializeAs<T> for Check<V, A> {
174 fn serialize_as<'a>(value: &'a T, state: &mut State) -> Result<Chunk<'a>, Error> {
175 A::serialize_as(value, state)
176 }
177
178 fn finish_as(value: &T, state: &mut State) -> Result<(), Error> {
179 A::finish_as(value, state)
180 }
181
182 fn is_optional_as(value: &T) -> bool {
183 A::is_optional_as(value)
184 }
185
186 fn container_shape_as(value: &T) -> ContainerShape {
187 A::container_shape_as(value)
188 }
189
190 fn describe_as(value: &T, d: &mut dyn Describe) {
191 A::describe_as(value, d)
192 }
193}
194
195struct CheckSink<'a, 'de, T, V> {
200 out: &'a mut Option<T>,
201 sink: OwnedSink<'de, T>,
202 start: Option<usize>,
204 _validator: PhantomData<fn() -> V>,
205}
206
207impl<'a, 'de, T, V> CheckSink<'a, 'de, T, V> {
208 fn begin(&mut self, state: &State) -> &mut (dyn Sink<'de> + '_) {
209 self.start = state.input_range().map(|range| range.start);
210 self.sink.borrow_mut()
211 }
212}
213
214impl<'a, 'de, T: Send, V: Validator<T>> Sink<'de> for CheckSink<'a, 'de, T, V> {
215 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
216 self.begin(state).atom(atom, state)
217 }
218
219 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
220 self.begin(state).borrowed_atom(atom, state)
221 }
222
223 fn map(&mut self, state: &mut State) -> Result<(), Error> {
224 self.begin(state).map(state)
225 }
226
227 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
228 self.begin(state).seq(state)
229 }
230
231 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
232 self.sink.borrow_mut().next_key(state)
233 }
234
235 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
236 self.sink.borrow_mut().next_value(state)
237 }
238
239 fn __private_key_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
240 self.sink.borrow_mut().__private_key_atom(atom, state)
241 }
242
243 fn __private_value_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
244 self.sink.borrow_mut().__private_value_atom(atom, state)
245 }
246
247 fn __private_borrowed_key_atom(
248 &mut self,
249 atom: Atom<'de>,
250 state: &mut State,
251 ) -> Result<(), Error> {
252 self.sink
253 .borrow_mut()
254 .__private_borrowed_key_atom(atom, state)
255 }
256
257 fn __private_borrowed_value_atom(
258 &mut self,
259 atom: Atom<'de>,
260 state: &mut State,
261 ) -> Result<(), Error> {
262 self.sink
263 .borrow_mut()
264 .__private_borrowed_value_atom(atom, state)
265 }
266
267 fn value_for_key(
268 &mut self,
269 key: &str,
270 state: &mut State,
271 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
272 self.sink.borrow_mut().value_for_key(key, state)
273 }
274
275 fn recover(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
276 self.sink.borrow_mut().recover(err, state)
277 }
278
279 fn finish(&mut self, state: &mut State) -> Result<(), Error> {
280 self.sink.borrow_mut().finish(state)?;
281 if let Some(value) = self.sink.take() {
282 if let Err(violation) = V::validate(&value) {
283 let err = violation.into_error();
284 return Err(match self.start {
285 Some(start) => err.with_offset(start),
286 None => err,
287 });
288 }
289 *self.out = Some(value);
290 }
291 Ok(())
292 }
293
294 fn expecting(&self) -> Cow<'_, str> {
295 self.sink.borrow().expecting()
296 }
297}