1use std::borrow::Cow;
3use std::fmt;
4use std::marker::PhantomData;
5
6use deser_core::de::{Deserialize, OwnedSink, Sink, SinkHandle};
7use deser_core::ser::{Chunk, Describe, Serialize};
8use deser_core::{Atom, ContainerShape, Error, ErrorKind, State};
9use deser_location::Locations;
10
11use crate::Validator;
12use crate::report::ReportHandle;
13
14pub struct Validated<T, V = ()> {
87 value: Option<T>,
88 error: Option<Error>,
89 _validator: PhantomData<fn() -> V>,
90}
91
92impl<T, V: Validator<T>> Validated<T, V> {
93 pub fn new(value: T) -> Validated<T, V> {
95 let error = V::validate(&value).err().map(|x| x.into_error());
96 Validated {
97 value: Some(value),
98 error,
99 _validator: PhantomData,
100 }
101 }
102}
103
104impl<T, V> Validated<T, V> {
105 pub fn from_error(error: Error) -> Validated<T, V> {
107 Validated {
108 value: None,
109 error: Some(error),
110 _validator: PhantomData,
111 }
112 }
113
114 pub fn is_valid(&self) -> bool {
116 self.error.is_none()
117 }
118
119 pub fn value(&self) -> Option<&T> {
121 match self.error {
122 None => self.value.as_ref(),
123 Some(_) => None,
124 }
125 }
126
127 pub fn unchecked_value(&self) -> Option<&T> {
131 self.value.as_ref()
132 }
133
134 pub fn error(&self) -> Option<&Error> {
138 self.error.as_ref()
139 }
140
141 pub fn into_result(self) -> Result<T, Error> {
143 match (self.value, self.error) {
144 (Some(value), None) => Ok(value),
145 (_, Some(err)) => Err(err),
146 (None, None) => Err(Error::new(ErrorKind::Unexpected, "missing value")),
147 }
148 }
149}
150
151impl<T: fmt::Debug, V> fmt::Debug for Validated<T, V> {
152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153 match self.error {
154 None => fmt::Debug::fmt(&self.value, f),
155 Some(ref err) => f
156 .debug_struct("Invalid")
157 .field("value", &self.value)
158 .field("error", &format_args!("{:#}", err))
159 .finish(),
160 }
161 }
162}
163
164impl<'de, T: Deserialize<'de>, V: Validator<T>> Deserialize<'de> for Validated<T, V> {
165 fn deserialize_into<'out>(
166 out: &'out mut Option<Self>,
167 state: &mut State,
168 ) -> SinkHandle<'out, 'de> {
169 SinkHandle::arena(
170 ValidatedSink {
171 out,
172 sink: Some(OwnedSink::deserialize(state)),
173 error: None,
174 start: None,
175 outer: None,
176 },
177 state,
178 )
179 }
180
181 fn initial_value() -> Option<Self> {
183 T::initial_value().map(Validated::new)
184 }
185}
186
187struct ValidatedSink<'a, 'de, T, V> {
188 out: &'a mut Option<Validated<T, V>>,
189 sink: Option<OwnedSink<'de, T>>,
191 error: Option<Error>,
192 start: Option<usize>,
194 outer: Option<bool>,
196}
197
198impl<'a, 'de, T, V> ValidatedSink<'a, 'de, T, V> {
199 fn sink(&mut self) -> Option<&mut (dyn Sink<'de> + '_)> {
201 self.sink.as_mut().map(|sink| sink.borrow_mut())
202 }
203
204 fn begin(&mut self, state: &mut State) -> Option<&mut (dyn Sink<'de> + '_)> {
208 if self.start.is_none() {
209 self.start = state.input_range().map(|range| range.start);
210 }
211 if self.outer.is_none() {
212 self.outer = Some(state.set_collect_errors(true));
213 }
214 self.sink()
215 }
216
217 fn end(&mut self, state: &mut State) {
220 if let Some(outer) = self.outer.take() {
221 state.set_collect_errors(outer);
222 }
223 }
224
225 fn fail(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
230 if state.discards_errors() || state.error_limit_reached() {
231 self.end(state);
232 return Err(err);
233 }
234 self.sink = None;
235 self.error = Some(state.attach_error_context(err));
236 Ok(())
237 }
238
239 fn check(&mut self, rv: Result<(), Error>, state: &mut State) -> Result<(), Error> {
241 match rv {
242 Ok(()) => Ok(()),
243 Err(err) => self.fail(err, state),
244 }
245 }
246}
247
248impl<'a, 'de, T: Send, V: Validator<T>> Sink<'de> for ValidatedSink<'a, 'de, T, V> {
249 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
250 let rv = match self.begin(state) {
251 Some(sink) => sink.atom(atom, state),
252 None => Ok(()),
253 };
254 self.check(rv, state)
255 }
256
257 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
258 let rv = match self.begin(state) {
259 Some(sink) => sink.borrowed_atom(atom, state),
260 None => Ok(()),
261 };
262 self.check(rv, state)
263 }
264
265 fn map(&mut self, state: &mut State) -> Result<(), Error> {
266 let rv = match self.begin(state) {
267 Some(sink) => sink.map(state),
268 None => Ok(()),
269 };
270 self.check(rv, state)
271 }
272
273 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
274 let rv = match self.begin(state) {
275 Some(sink) => sink.seq(state),
276 None => Ok(()),
277 };
278 self.check(rv, state)
279 }
280
281 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
284 match self.sink() {
285 Some(sink) => sink.next_key(state),
286 None => Ok(SinkHandle::null()),
287 }
288 }
289
290 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
291 match self.sink() {
292 Some(sink) => sink.next_value(state),
293 None => Ok(SinkHandle::null()),
294 }
295 }
296
297 fn __private_key_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
298 match self.sink() {
299 Some(sink) => sink.__private_key_atom(atom, state),
300 None => Ok(()),
301 }
302 }
303
304 fn __private_value_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
305 match self.sink() {
306 Some(sink) => sink.__private_value_atom(atom, state),
307 None => Ok(()),
308 }
309 }
310
311 fn __private_borrowed_key_atom(
312 &mut self,
313 atom: Atom<'de>,
314 state: &mut State,
315 ) -> Result<(), Error> {
316 match self.sink() {
317 Some(sink) => sink.__private_borrowed_key_atom(atom, state),
318 None => Ok(()),
319 }
320 }
321
322 fn __private_borrowed_value_atom(
323 &mut self,
324 atom: Atom<'de>,
325 state: &mut State,
326 ) -> Result<(), Error> {
327 match self.sink() {
328 Some(sink) => sink.__private_borrowed_value_atom(atom, state),
329 None => Ok(()),
330 }
331 }
332
333 fn value_for_key(
334 &mut self,
335 key: &str,
336 state: &mut State,
337 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
338 match self.sink() {
339 Some(sink) => sink.value_for_key(key, state),
340 None => Ok(None),
341 }
342 }
343
344 fn recover(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
345 let rv = match self.sink() {
348 Some(sink) => sink.recover(err, state),
349 None => Ok(()),
350 };
351 self.check(rv, state)
352 }
353
354 fn finish(&mut self, state: &mut State) -> Result<(), Error> {
355 let rv = match self.sink() {
356 Some(sink) => sink.finish(state),
357 None => Ok(()),
358 };
359 self.check(rv, state)?;
360 self.end(state);
361 let value = self.sink.as_mut().and_then(|sink| sink.take());
362 if let Some(ref value) = value
363 && let Err(violation) = V::validate(value)
364 {
365 let err = violation.into_error();
367 let err = match self.start {
368 Some(start) => err.with_offset(start),
369 None => err,
370 };
371 if state.discards_errors() {
372 return Err(err);
373 }
374 self.error = Some(state.attach_error_context(err));
375 }
376 if value.is_none() && self.error.is_none() {
377 return Ok(());
378 }
379 let error = self.error.take().map(|err| report_error(err, state));
380 *self.out = Some(Validated {
381 value,
382 error,
383 _validator: PhantomData,
384 });
385 Ok(())
386 }
387
388 fn expecting(&self) -> Cow<'_, str> {
389 match self.sink {
390 Some(ref sink) => sink.borrow().expecting(),
391 None => Cow::Borrowed("compatible type"),
392 }
393 }
394}
395
396fn report_error(err: Error, state: &mut State) -> Error {
398 let err = match Locations::source_map(state) {
399 Some(source_map) => err.resolve_position(source_map.source().as_bytes()),
400 None => err,
401 };
402 ReportHandle::report(&err, state);
403 err
404}
405
406impl<T: Serialize, V> Serialize for Validated<T, V> {
407 fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
408 match self.value {
409 Some(ref value) => value.serialize(state),
410 None => Ok(Chunk::Atom(Atom::Null)),
411 }
412 }
413
414 fn finish(&self, state: &mut State) -> Result<(), Error> {
415 match self.value {
416 Some(ref value) => value.finish(state),
417 None => Ok(()),
418 }
419 }
420
421 fn is_optional(&self) -> bool {
422 match self.value {
423 Some(ref value) => value.is_optional(),
424 None => true,
425 }
426 }
427
428 fn container_shape(&self) -> ContainerShape {
429 match self.value {
430 Some(ref value) => value.container_shape(),
431 None => ContainerShape::new(),
432 }
433 }
434
435 fn describe(&self, d: &mut dyn Describe) {
436 if let Some(ref value) = self.value {
437 value.describe(d)
438 }
439 }
440}