csv_pretty/
deserializer.rs

1use std::{error::Error as StdError, fmt, iter, num, str};
2
3use serde_core::{
4    de::value::BorrowedBytesDeserializer,
5    de::{
6        Deserialize, DeserializeSeed, Deserializer, EnumAccess,
7        Error as SerdeError, IntoDeserializer, MapAccess, SeqAccess,
8        Unexpected, VariantAccess, Visitor,
9    },
10};
11
12use crate::{
13    byte_record::{ByteRecord, ByteRecordIter},
14    error::{Error, ErrorKind},
15    string_record::{StringRecord, StringRecordIter},
16};
17
18use self::DeserializeErrorKind as DEK;
19
20pub fn deserialize_string_record<'de, D: Deserialize<'de>>(
21    record: &'de StringRecord,
22    headers: Option<&'de StringRecord>,
23) -> Result<D, Error> {
24    let mut deser = DeRecordWrap(
25        DeStringRecord {
26            it: record.iter().peekable(),
27            headers: headers.map(|r| r.iter()),
28            field: 0,
29        },
30        None,
31    );
32    D::deserialize(&mut deser).map_err(|err| {
33        Error::new(ErrorKind::Deserialize {
34            pos: record.position().cloned(),
35            err,
36        })
37    })
38}
39
40pub fn deserialize_byte_record<'de, D: Deserialize<'de>>(
41    record: &'de ByteRecord,
42    headers: Option<&'de ByteRecord>,
43) -> Result<D, Error> {
44    let mut deser = DeRecordWrap(
45        DeByteRecord {
46            it: record.iter().peekable(),
47            headers: headers.map(|r| r.iter()),
48            field: 0,
49        },
50        None,
51    );
52    D::deserialize(&mut deser).map_err(|err| {
53        Error::new(ErrorKind::Deserialize {
54            pos: record.position().cloned(),
55            err,
56        })
57    })
58}
59
60/// An over-engineered internal trait that permits writing a single Serde
61/// deserializer that works on both ByteRecord and StringRecord.
62///
63/// We *could* implement a single deserializer on `ByteRecord` and simply
64/// convert `StringRecord`s to `ByteRecord`s, but then the implementation
65/// would be required to redo UTF-8 validation checks in certain places.
66///
67/// How does this work? We create a new `DeRecordWrap` type that wraps
68/// either a `StringRecord` or a `ByteRecord`. We then implement
69/// `DeRecord` for `DeRecordWrap<ByteRecord>` and `DeRecordWrap<StringRecord>`.
70/// Finally, we impl `serde::Deserialize` for `DeRecordWrap<T>` where
71/// `T: DeRecord`. That is, the `DeRecord` type corresponds to the differences
72/// between deserializing into a `ByteRecord` and deserializing into a
73/// `StringRecord`.
74///
75/// The lifetime `'r` refers to the lifetime of the underlying record.
76trait DeRecord<'r> {
77    /// Returns true if and only if this deserialize has access to headers.
78    fn has_headers(&self) -> bool;
79
80    /// Extracts the next string header value from the underlying record.
81    fn next_header(&mut self) -> Result<Option<&'r str>, DeserializeError>;
82
83    /// Extracts the next raw byte header value from the underlying record.
84    fn next_header_bytes(
85        &mut self,
86    ) -> Result<Option<&'r [u8]>, DeserializeError>;
87
88    /// Extracts the next string field from the underlying record.
89    fn next_field(&mut self) -> Result<&'r str, DeserializeError>;
90
91    /// Extracts the next raw byte field from the underlying record.
92    fn next_field_bytes(&mut self) -> Result<&'r [u8], DeserializeError>;
93
94    /// Peeks at the next field from the underlying record.
95    fn peek_field(&mut self) -> Option<&'r [u8]>;
96
97    /// Returns an error corresponding to the most recently extracted field.
98    fn error(&self, kind: DeserializeErrorKind) -> DeserializeError;
99
100    /// Infer the type of the next field and deserialize it.
101    fn infer_deserialize<'de, V: Visitor<'de>>(
102        &mut self,
103        visitor: V,
104    ) -> Result<V::Value, DeserializeError>;
105}
106
107struct DeRecordWrap<T>(T, Option<Vec<u8>>);
108
109impl<'r, T: DeRecord<'r>> DeRecord<'r> for DeRecordWrap<T> {
110    #[inline]
111    fn has_headers(&self) -> bool {
112        self.0.has_headers()
113    }
114
115    #[inline]
116    fn next_header(&mut self) -> Result<Option<&'r str>, DeserializeError> {
117        self.0.next_header()
118    }
119
120    #[inline]
121    fn next_header_bytes(
122        &mut self,
123    ) -> Result<Option<&'r [u8]>, DeserializeError> {
124        self.0.next_header_bytes()
125    }
126
127    #[inline]
128    fn next_field(&mut self) -> Result<&'r str, DeserializeError> {
129        self.0.next_field()
130    }
131
132    #[inline]
133    fn next_field_bytes(&mut self) -> Result<&'r [u8], DeserializeError> {
134        self.0.next_field_bytes()
135    }
136
137    #[inline]
138    fn peek_field(&mut self) -> Option<&'r [u8]> {
139        self.0.peek_field()
140    }
141
142    #[inline]
143    fn error(&self, kind: DeserializeErrorKind) -> DeserializeError {
144        self.0.error(kind)
145    }
146
147    #[inline]
148    fn infer_deserialize<'de, V: Visitor<'de>>(
149        &mut self,
150        visitor: V,
151    ) -> Result<V::Value, DeserializeError> {
152        self.0.infer_deserialize(visitor)
153    }
154}
155
156struct DeStringRecord<'r> {
157    it: iter::Peekable<StringRecordIter<'r>>,
158    headers: Option<StringRecordIter<'r>>,
159    field: u64,
160}
161
162impl<'r> DeRecord<'r> for DeStringRecord<'r> {
163    #[inline]
164    fn has_headers(&self) -> bool {
165        self.headers.is_some()
166    }
167
168    #[inline]
169    fn next_header(&mut self) -> Result<Option<&'r str>, DeserializeError> {
170        Ok(self.headers.as_mut().and_then(|it| it.next()))
171    }
172
173    #[inline]
174    fn next_header_bytes(
175        &mut self,
176    ) -> Result<Option<&'r [u8]>, DeserializeError> {
177        Ok(self.next_header()?.map(|s| s.as_bytes()))
178    }
179
180    #[inline]
181    fn next_field(&mut self) -> Result<&'r str, DeserializeError> {
182        match self.it.next() {
183            Some(field) => {
184                self.field += 1;
185                Ok(field)
186            }
187            None => Err(DeserializeError {
188                field: None,
189                kind: DEK::UnexpectedEndOfRow,
190            }),
191        }
192    }
193
194    #[inline]
195    fn next_field_bytes(&mut self) -> Result<&'r [u8], DeserializeError> {
196        self.next_field().map(|s| s.as_bytes())
197    }
198
199    #[inline]
200    fn peek_field(&mut self) -> Option<&'r [u8]> {
201        self.it.peek().map(|s| s.as_bytes())
202    }
203
204    fn error(&self, kind: DeserializeErrorKind) -> DeserializeError {
205        DeserializeError { field: Some(self.field.saturating_sub(1)), kind }
206    }
207
208    fn infer_deserialize<'de, V: Visitor<'de>>(
209        &mut self,
210        visitor: V,
211    ) -> Result<V::Value, DeserializeError> {
212        let x = self.next_field()?;
213        if x == "true" {
214            visitor.visit_bool(true)
215        } else if x == "false" {
216            visitor.visit_bool(false)
217        } else if let Some(n) = try_positive_integer64(x) {
218            visitor.visit_u64(n)
219        } else if let Some(n) = try_negative_integer64(x) {
220            visitor.visit_i64(n)
221        } else if let Some(n) = try_positive_integer128(x) {
222            visitor.visit_u128(n)
223        } else if let Some(n) = try_negative_integer128(x) {
224            visitor.visit_i128(n)
225        } else if let Some(n) = try_float(x) {
226            visitor.visit_f64(n)
227        } else {
228            visitor.visit_str(x)
229        }
230    }
231}
232
233struct DeByteRecord<'r> {
234    it: iter::Peekable<ByteRecordIter<'r>>,
235    headers: Option<ByteRecordIter<'r>>,
236    field: u64,
237}
238
239impl<'r> DeRecord<'r> for DeByteRecord<'r> {
240    #[inline]
241    fn has_headers(&self) -> bool {
242        self.headers.is_some()
243    }
244
245    #[inline]
246    fn next_header(&mut self) -> Result<Option<&'r str>, DeserializeError> {
247        match self.next_header_bytes() {
248            Ok(Some(field)) => Ok(Some(
249                str::from_utf8(field)
250                    .map_err(|err| self.error(DEK::InvalidUtf8(err)))?,
251            )),
252            Ok(None) => Ok(None),
253            Err(err) => Err(err),
254        }
255    }
256
257    #[inline]
258    fn next_header_bytes(
259        &mut self,
260    ) -> Result<Option<&'r [u8]>, DeserializeError> {
261        Ok(self.headers.as_mut().and_then(|it| it.next()))
262    }
263
264    #[inline]
265    fn next_field(&mut self) -> Result<&'r str, DeserializeError> {
266        self.next_field_bytes().and_then(|field| {
267            str::from_utf8(field)
268                .map_err(|err| self.error(DEK::InvalidUtf8(err)))
269        })
270    }
271
272    #[inline]
273    fn next_field_bytes(&mut self) -> Result<&'r [u8], DeserializeError> {
274        match self.it.next() {
275            Some(field) => {
276                self.field += 1;
277                Ok(field)
278            }
279            None => Err(DeserializeError {
280                field: None,
281                kind: DEK::UnexpectedEndOfRow,
282            }),
283        }
284    }
285
286    #[inline]
287    fn peek_field(&mut self) -> Option<&'r [u8]> {
288        self.it.peek().copied()
289    }
290
291    fn error(&self, kind: DeserializeErrorKind) -> DeserializeError {
292        DeserializeError { field: Some(self.field.saturating_sub(1)), kind }
293    }
294
295    fn infer_deserialize<'de, V: Visitor<'de>>(
296        &mut self,
297        visitor: V,
298    ) -> Result<V::Value, DeserializeError> {
299        let x = self.next_field_bytes()?;
300        if x == b"true" {
301            visitor.visit_bool(true)
302        } else if x == b"false" {
303            visitor.visit_bool(false)
304        } else if let Some(n) = try_positive_integer64_bytes(x) {
305            visitor.visit_u64(n)
306        } else if let Some(n) = try_negative_integer64_bytes(x) {
307            visitor.visit_i64(n)
308        } else if let Some(n) = try_positive_integer128_bytes(x) {
309            visitor.visit_u128(n)
310        } else if let Some(n) = try_negative_integer128_bytes(x) {
311            visitor.visit_i128(n)
312        } else if let Some(n) = try_float_bytes(x) {
313            visitor.visit_f64(n)
314        } else if let Ok(s) = str::from_utf8(x) {
315            visitor.visit_str(s)
316        } else {
317            visitor.visit_bytes(x)
318        }
319    }
320}
321
322macro_rules! deserialize_int {
323    ($method:ident, $visit:ident, $inttype:ty) => {
324        fn $method<V: Visitor<'de>>(
325            self,
326            visitor: V,
327        ) -> Result<V::Value, Self::Error> {
328            let field = self.next_field()?;
329            let num = if let Some(digits) = field.strip_prefix("0x") {
330                <$inttype>::from_str_radix(digits, 16)
331            } else {
332                field.parse()
333            };
334            visitor.$visit(num.map_err(|err| self.error(DEK::ParseInt(err)))?)
335        }
336    };
337}
338
339impl<'a, 'de: 'a, T: DeRecord<'de>> Deserializer<'de>
340    for &'a mut DeRecordWrap<T>
341{
342    type Error = DeserializeError;
343
344    fn deserialize_any<V: Visitor<'de>>(
345        self,
346        visitor: V,
347    ) -> Result<V::Value, Self::Error> {
348        self.infer_deserialize(visitor)
349    }
350
351    fn deserialize_bool<V: Visitor<'de>>(
352        self,
353        visitor: V,
354    ) -> Result<V::Value, Self::Error> {
355        visitor.visit_bool(
356            self.next_field()?
357                .parse()
358                .map_err(|err| self.error(DEK::ParseBool(err)))?,
359        )
360    }
361
362    deserialize_int!(deserialize_u8, visit_u8, u8);
363    deserialize_int!(deserialize_u16, visit_u16, u16);
364    deserialize_int!(deserialize_u32, visit_u32, u32);
365    deserialize_int!(deserialize_u64, visit_u64, u64);
366    deserialize_int!(deserialize_u128, visit_u128, u128);
367    deserialize_int!(deserialize_i8, visit_i8, i8);
368    deserialize_int!(deserialize_i16, visit_i16, i16);
369    deserialize_int!(deserialize_i32, visit_i32, i32);
370    deserialize_int!(deserialize_i64, visit_i64, i64);
371    deserialize_int!(deserialize_i128, visit_i128, i128);
372
373    fn deserialize_f32<V: Visitor<'de>>(
374        self,
375        visitor: V,
376    ) -> Result<V::Value, Self::Error> {
377        visitor.visit_f32(
378            self.next_field()?
379                .parse()
380                .map_err(|err| self.error(DEK::ParseFloat(err)))?,
381        )
382    }
383
384    fn deserialize_f64<V: Visitor<'de>>(
385        self,
386        visitor: V,
387    ) -> Result<V::Value, Self::Error> {
388        visitor.visit_f64(
389            self.next_field()?
390                .parse()
391                .map_err(|err| self.error(DEK::ParseFloat(err)))?,
392        )
393    }
394
395    fn deserialize_char<V: Visitor<'de>>(
396        self,
397        visitor: V,
398    ) -> Result<V::Value, Self::Error> {
399        let field = self.next_field()?;
400        let len = field.chars().count();
401        if len != 1 {
402            return Err(self.error(DEK::Message(format!(
403                "expected single character but got {} characters in '{}'",
404                len, field
405            ))));
406        }
407        visitor.visit_char(field.chars().next().unwrap())
408    }
409
410    fn deserialize_str<V: Visitor<'de>>(
411        self,
412        visitor: V,
413    ) -> Result<V::Value, Self::Error> {
414        self.next_field().and_then(|f| visitor.visit_borrowed_str(f))
415    }
416
417    fn deserialize_string<V: Visitor<'de>>(
418        self,
419        visitor: V,
420    ) -> Result<V::Value, Self::Error> {
421        self.next_field().and_then(|f| visitor.visit_str(f))
422    }
423
424    fn deserialize_bytes<V: Visitor<'de>>(
425        self,
426        visitor: V,
427    ) -> Result<V::Value, Self::Error> {
428        self.next_field_bytes().and_then(|f| visitor.visit_borrowed_bytes(f))
429    }
430
431    fn deserialize_byte_buf<V: Visitor<'de>>(
432        self,
433        visitor: V,
434    ) -> Result<V::Value, Self::Error> {
435        self.next_field_bytes()
436            .and_then(|f| visitor.visit_byte_buf(f.to_vec()))
437    }
438
439    fn deserialize_option<V: Visitor<'de>>(
440        self,
441        visitor: V,
442    ) -> Result<V::Value, Self::Error> {
443        match self.peek_field() {
444            None => visitor.visit_none(),
445            Some([]) => {
446                self.next_field().expect("empty field");
447                visitor.visit_none()
448            }
449            Some(_) => visitor.visit_some(self),
450        }
451    }
452
453    fn deserialize_unit<V: Visitor<'de>>(
454        self,
455        visitor: V,
456    ) -> Result<V::Value, Self::Error> {
457        visitor.visit_unit()
458    }
459
460    fn deserialize_unit_struct<V: Visitor<'de>>(
461        self,
462        _name: &'static str,
463        visitor: V,
464    ) -> Result<V::Value, Self::Error> {
465        visitor.visit_unit()
466    }
467
468    fn deserialize_newtype_struct<V: Visitor<'de>>(
469        self,
470        _name: &'static str,
471        visitor: V,
472    ) -> Result<V::Value, Self::Error> {
473        visitor.visit_newtype_struct(self)
474    }
475
476    fn deserialize_seq<V: Visitor<'de>>(
477        self,
478        visitor: V,
479    ) -> Result<V::Value, Self::Error> {
480        visitor.visit_seq(self)
481    }
482
483    fn deserialize_tuple<V: Visitor<'de>>(
484        self,
485        _len: usize,
486        visitor: V,
487    ) -> Result<V::Value, Self::Error> {
488        visitor.visit_seq(self)
489    }
490
491    fn deserialize_tuple_struct<V: Visitor<'de>>(
492        self,
493        _name: &'static str,
494        _len: usize,
495        visitor: V,
496    ) -> Result<V::Value, Self::Error> {
497        visitor.visit_seq(self)
498    }
499
500    fn deserialize_map<V: Visitor<'de>>(
501        self,
502        visitor: V,
503    ) -> Result<V::Value, Self::Error> {
504        if !self.has_headers() {
505            visitor.visit_seq(self)
506        } else {
507            visitor.visit_map(self)
508        }
509    }
510
511    fn deserialize_struct<V: Visitor<'de>>(
512        self,
513        _name: &'static str,
514        _fields: &'static [&'static str],
515        visitor: V,
516    ) -> Result<V::Value, Self::Error> {
517        if !self.has_headers() {
518            visitor.visit_seq(self)
519        } else {
520            visitor.visit_map(self)
521        }
522    }
523
524    fn deserialize_identifier<V: Visitor<'de>>(
525        self,
526        _visitor: V,
527    ) -> Result<V::Value, Self::Error> {
528        Err(self.error(DEK::Unsupported("deserialize_identifier".into())))
529    }
530
531    fn deserialize_enum<V: Visitor<'de>>(
532        self,
533        _name: &'static str,
534        _variants: &'static [&'static str],
535        visitor: V,
536    ) -> Result<V::Value, Self::Error> {
537        visitor.visit_enum(self)
538    }
539
540    fn deserialize_ignored_any<V: Visitor<'de>>(
541        self,
542        visitor: V,
543    ) -> Result<V::Value, Self::Error> {
544        // Read and drop the next field.
545        // This code is reached, e.g., when trying to deserialize a header
546        // that doesn't exist in the destination struct.
547        let _ = self.next_field_bytes()?;
548        visitor.visit_unit()
549    }
550}
551
552impl<'a, 'de: 'a, T: DeRecord<'de>> EnumAccess<'de>
553    for &'a mut DeRecordWrap<T>
554{
555    type Error = DeserializeError;
556    type Variant = Self;
557
558    fn variant_seed<V: DeserializeSeed<'de>>(
559        self,
560        seed: V,
561    ) -> Result<(V::Value, Self::Variant), Self::Error> {
562        let variant_name = self.next_field()?;
563        seed.deserialize(variant_name.into_deserializer()).map(|v| (v, self))
564    }
565}
566
567impl<'a, 'de: 'a, T: DeRecord<'de>> VariantAccess<'de>
568    for &'a mut DeRecordWrap<T>
569{
570    type Error = DeserializeError;
571
572    fn unit_variant(self) -> Result<(), Self::Error> {
573        Ok(())
574    }
575
576    fn newtype_variant_seed<U: DeserializeSeed<'de>>(
577        self,
578        _seed: U,
579    ) -> Result<U::Value, Self::Error> {
580        let unexp = Unexpected::UnitVariant;
581        Err(DeserializeError::invalid_type(unexp, &"newtype variant"))
582    }
583
584    fn tuple_variant<V: Visitor<'de>>(
585        self,
586        _len: usize,
587        _visitor: V,
588    ) -> Result<V::Value, Self::Error> {
589        let unexp = Unexpected::UnitVariant;
590        Err(DeserializeError::invalid_type(unexp, &"tuple variant"))
591    }
592
593    fn struct_variant<V: Visitor<'de>>(
594        self,
595        _fields: &'static [&'static str],
596        _visitor: V,
597    ) -> Result<V::Value, Self::Error> {
598        let unexp = Unexpected::UnitVariant;
599        Err(DeserializeError::invalid_type(unexp, &"struct variant"))
600    }
601}
602
603impl<'a, 'de: 'a, T: DeRecord<'de>> SeqAccess<'de>
604    for &'a mut DeRecordWrap<T>
605{
606    type Error = DeserializeError;
607
608    fn next_element_seed<U: DeserializeSeed<'de>>(
609        &mut self,
610        seed: U,
611    ) -> Result<Option<U::Value>, Self::Error> {
612        if self.peek_field().is_none() {
613            Ok(None)
614        } else {
615            seed.deserialize(&mut **self).map(Some)
616        }
617    }
618}
619
620impl<'a, 'de: 'a, T: DeRecord<'de>> MapAccess<'de>
621    for &'a mut DeRecordWrap<T>
622{
623    type Error = DeserializeError;
624
625    fn next_key_seed<K: DeserializeSeed<'de>>(
626        &mut self,
627        seed: K,
628    ) -> Result<Option<K::Value>, Self::Error> {
629        assert!(self.has_headers());
630        let field = match self.next_header_bytes()? {
631            None => return Ok(None),
632            Some(field) => field,
633        };
634        self.1 = Some(field.to_owned());
635        seed.deserialize(BorrowedBytesDeserializer::new(field)).map(Some)
636    }
637
638    fn next_value_seed<K: DeserializeSeed<'de>>(
639        &mut self,
640        seed: K,
641    ) -> Result<K::Value, Self::Error> {
642        let field_value = self.peek_field();
643        seed.deserialize(&mut **self).map_err(|e| {
644            // enhance error with field name and field value
645            let DeserializeError { field, kind } = e;
646            DeserializeError {
647                field,
648                kind: DeserializeErrorKind::Message(format!(
649                    "{}. Field '{}' has value '{}'",
650                    kind.to_string(),
651                    self.1
652                        .clone()
653                        .map_or("".to_owned(), |x| String::from_utf8(x)
654                            .unwrap()),
655                    field_value.map_or("n/a".to_owned(), |d| {
656                        String::from_utf8(d.to_owned()).unwrap()
657                    })
658                )),
659            }
660        })
661    }
662}
663
664/// An Serde deserialization error.
665#[derive(Clone, Debug, Eq, PartialEq)]
666pub struct DeserializeError {
667    field: Option<u64>,
668    kind: DeserializeErrorKind,
669}
670
671/// The type of a Serde deserialization error.
672#[derive(Clone, Debug, Eq, PartialEq)]
673pub enum DeserializeErrorKind {
674    /// A generic Serde deserialization error.
675    Message(String),
676    /// A generic Serde unsupported error.
677    Unsupported(String),
678    /// This error occurs when a Rust type expects to decode another field
679    /// from a row, but no more fields exist.
680    UnexpectedEndOfRow,
681    /// This error occurs when UTF-8 validation on a field fails. UTF-8
682    /// validation is only performed when the Rust type requires it (e.g.,
683    /// a `String` or `&str` type).
684    InvalidUtf8(str::Utf8Error),
685    /// This error occurs when a boolean value fails to parse.
686    ParseBool(str::ParseBoolError),
687    /// This error occurs when an integer value fails to parse.
688    ParseInt(num::ParseIntError),
689    /// This error occurs when a float value fails to parse.
690    ParseFloat(num::ParseFloatError),
691}
692
693impl SerdeError for DeserializeError {
694    fn custom<T: fmt::Display>(msg: T) -> DeserializeError {
695        DeserializeError { field: None, kind: DEK::Message(msg.to_string()) }
696    }
697}
698
699impl StdError for DeserializeError {
700    fn description(&self) -> &str {
701        self.kind.description()
702    }
703}
704
705impl fmt::Display for DeserializeError {
706    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
707        if let Some(field) = self.field {
708            write!(f, "field {}: {}", field, self.kind)
709        } else {
710            write!(f, "{}", self.kind)
711        }
712    }
713}
714
715impl fmt::Display for DeserializeErrorKind {
716    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
717        use self::DeserializeErrorKind::*;
718
719        match *self {
720            Message(ref msg) => write!(f, "{}", msg),
721            Unsupported(ref which) => {
722                write!(f, "unsupported deserializer method: {}", which)
723            }
724            UnexpectedEndOfRow => write!(f, "{}", self.description()),
725            InvalidUtf8(ref err) => err.fmt(f),
726            ParseBool(ref err) => err.fmt(f),
727            ParseInt(ref err) => err.fmt(f),
728            ParseFloat(ref err) => err.fmt(f),
729        }
730    }
731}
732
733impl DeserializeError {
734    /// Return the field index (starting at 0) of this error, if available.
735    pub fn field(&self) -> Option<u64> {
736        self.field
737    }
738
739    /// Return the underlying error kind.
740    pub fn kind(&self) -> &DeserializeErrorKind {
741        &self.kind
742    }
743}
744
745impl DeserializeErrorKind {
746    #[allow(deprecated)]
747    fn description(&self) -> &str {
748        use self::DeserializeErrorKind::*;
749
750        match *self {
751            Message(_) => "deserialization error",
752            Unsupported(_) => "unsupported deserializer method",
753            UnexpectedEndOfRow => "expected field, but got end of row",
754            InvalidUtf8(ref err) => err.description(),
755            ParseBool(ref err) => err.description(),
756            ParseInt(ref err) => err.description(),
757            ParseFloat(ref err) => err.description(),
758        }
759    }
760}
761
762fn try_positive_integer128(s: &str) -> Option<u128> {
763    s.parse().ok()
764}
765
766fn try_negative_integer128(s: &str) -> Option<i128> {
767    s.parse().ok()
768}
769
770fn try_positive_integer64(s: &str) -> Option<u64> {
771    s.parse().ok()
772}
773
774fn try_negative_integer64(s: &str) -> Option<i64> {
775    s.parse().ok()
776}
777
778fn try_float(s: &str) -> Option<f64> {
779    s.parse().ok()
780}
781
782fn try_positive_integer64_bytes(s: &[u8]) -> Option<u64> {
783    str::from_utf8(s).ok().and_then(|s| s.parse().ok())
784}
785
786fn try_negative_integer64_bytes(s: &[u8]) -> Option<i64> {
787    str::from_utf8(s).ok().and_then(|s| s.parse().ok())
788}
789
790fn try_positive_integer128_bytes(s: &[u8]) -> Option<u128> {
791    str::from_utf8(s).ok().and_then(|s| s.parse().ok())
792}
793
794fn try_negative_integer128_bytes(s: &[u8]) -> Option<i128> {
795    str::from_utf8(s).ok().and_then(|s| s.parse().ok())
796}
797
798fn try_float_bytes(s: &[u8]) -> Option<f64> {
799    str::from_utf8(s).ok().and_then(|s| s.parse().ok())
800}
801
802#[cfg(test)]
803mod tests {
804    use std::collections::HashMap;
805
806    use {
807        bstr::BString,
808        serde::{de::DeserializeOwned, Deserialize},
809    };
810
811    use crate::{
812        byte_record::ByteRecord, error::Error, string_record::StringRecord,
813    };
814
815    use super::{deserialize_byte_record, deserialize_string_record};
816
817    fn de<D: DeserializeOwned>(fields: &[&str]) -> Result<D, Error> {
818        let record = StringRecord::from(fields);
819        deserialize_string_record(&record, None)
820    }
821
822    fn de_headers<D: DeserializeOwned>(
823        headers: &[&str],
824        fields: &[&str],
825    ) -> Result<D, Error> {
826        let headers = StringRecord::from(headers);
827        let record = StringRecord::from(fields);
828        deserialize_string_record(&record, Some(&headers))
829    }
830
831    fn b<T: AsRef<[u8]> + ?Sized>(bytes: &T) -> &[u8] {
832        bytes.as_ref()
833    }
834
835    #[test]
836    fn with_header() {
837        #[derive(Deserialize, Debug, PartialEq)]
838        struct Foo {
839            z: f64,
840            y: i32,
841            x: String,
842        }
843
844        let got: Foo =
845            de_headers(&["x", "y", "z"], &["hi", "42", "1.3"]).unwrap();
846        assert_eq!(got, Foo { x: "hi".into(), y: 42, z: 1.3 });
847    }
848
849    #[test]
850    fn with_header_unknown() {
851        #[derive(Deserialize, Debug, PartialEq)]
852        #[serde(deny_unknown_fields)]
853        struct Foo {
854            z: f64,
855            y: i32,
856            x: String,
857        }
858        assert!(de_headers::<Foo>(
859            &["a", "x", "y", "z"],
860            &["foo", "hi", "42", "1.3"],
861        )
862        .is_err());
863    }
864
865    #[test]
866    fn with_header_missing() {
867        #[derive(Deserialize, Debug, PartialEq)]
868        struct Foo {
869            z: f64,
870            y: i32,
871            x: String,
872        }
873        assert!(de_headers::<Foo>(&["y", "z"], &["42", "1.3"],).is_err());
874    }
875
876    #[test]
877    fn with_header_missing_ok() {
878        #[derive(Deserialize, Debug, PartialEq)]
879        struct Foo {
880            z: f64,
881            y: i32,
882            x: Option<String>,
883        }
884
885        let got: Foo = de_headers(&["y", "z"], &["42", "1.3"]).unwrap();
886        assert_eq!(got, Foo { x: None, y: 42, z: 1.3 });
887    }
888
889    #[test]
890    fn with_header_no_fields() {
891        #[derive(Deserialize, Debug, PartialEq)]
892        struct Foo {
893            z: f64,
894            y: i32,
895            x: Option<String>,
896        }
897
898        let got = de_headers::<Foo>(&["y", "z"], &[]);
899        assert!(got.is_err());
900    }
901
902    #[test]
903    fn with_header_empty() {
904        #[derive(Deserialize, Debug, PartialEq)]
905        struct Foo {
906            z: f64,
907            y: i32,
908            x: Option<String>,
909        }
910
911        let got = de_headers::<Foo>(&[], &[]);
912        assert!(got.is_err());
913    }
914
915    #[test]
916    fn with_header_empty_ok() {
917        #[derive(Deserialize, Debug, PartialEq)]
918        struct Foo;
919
920        #[derive(Deserialize, Debug, PartialEq)]
921        struct Bar {}
922
923        let got = de_headers::<Foo>(&[], &[]);
924        assert_eq!(got.unwrap(), Foo);
925
926        let got = de_headers::<Bar>(&[], &[]);
927        assert_eq!(got.unwrap(), Bar {});
928
929        let got = de_headers::<()>(&[], &[]);
930        assert_eq!(got.unwrap(), ());
931    }
932
933    #[test]
934    fn without_header() {
935        #[derive(Deserialize, Debug, PartialEq)]
936        struct Foo {
937            z: f64,
938            y: i32,
939            x: String,
940        }
941
942        let got: Foo = de(&["1.3", "42", "hi"]).unwrap();
943        assert_eq!(got, Foo { x: "hi".into(), y: 42, z: 1.3 });
944    }
945
946    #[test]
947    fn no_fields() {
948        assert!(de::<String>(&[]).is_err());
949    }
950
951    #[test]
952    fn one_field() {
953        let got: i32 = de(&["42"]).unwrap();
954        assert_eq!(got, 42);
955    }
956
957    #[test]
958    fn one_field_128() {
959        let got: i128 = de(&["2010223372036854775808"]).unwrap();
960        assert_eq!(got, 2010223372036854775808);
961    }
962
963    #[test]
964    fn two_fields() {
965        let got: (i32, bool) = de(&["42", "true"]).unwrap();
966        assert_eq!(got, (42, true));
967
968        #[derive(Deserialize, Debug, PartialEq)]
969        struct Foo(i32, bool);
970
971        let got: Foo = de(&["42", "true"]).unwrap();
972        assert_eq!(got, Foo(42, true));
973    }
974
975    #[test]
976    fn two_fields_too_many() {
977        let got: (i32, bool) = de(&["42", "true", "z", "z"]).unwrap();
978        assert_eq!(got, (42, true));
979    }
980
981    #[test]
982    fn two_fields_too_few() {
983        assert!(de::<(i32, bool)>(&["42"]).is_err());
984    }
985
986    #[test]
987    fn one_char() {
988        let got: char = de(&["a"]).unwrap();
989        assert_eq!(got, 'a');
990    }
991
992    #[test]
993    fn no_chars() {
994        assert!(de::<char>(&[""]).is_err());
995    }
996
997    #[test]
998    fn too_many_chars() {
999        assert!(de::<char>(&["ab"]).is_err());
1000    }
1001
1002    #[test]
1003    fn simple_seq() {
1004        let got: Vec<i32> = de(&["1", "5", "10"]).unwrap();
1005        assert_eq!(got, vec![1, 5, 10]);
1006    }
1007
1008    #[test]
1009    fn simple_hex_seq() {
1010        let got: Vec<i32> = de(&["0x7F", "0xA9", "0x10"]).unwrap();
1011        assert_eq!(got, vec![0x7F, 0xA9, 0x10]);
1012    }
1013
1014    #[test]
1015    fn mixed_hex_seq() {
1016        let got: Vec<i32> = de(&["0x7F", "0xA9", "10"]).unwrap();
1017        assert_eq!(got, vec![0x7F, 0xA9, 10]);
1018    }
1019
1020    #[test]
1021    fn bad_hex_seq() {
1022        assert!(de::<Vec<u8>>(&["7F", "0xA9", "10"]).is_err());
1023    }
1024
1025    #[test]
1026    fn seq_in_struct() {
1027        #[derive(Deserialize, Debug, PartialEq)]
1028        struct Foo {
1029            xs: Vec<i32>,
1030        }
1031        let got: Foo = de(&["1", "5", "10"]).unwrap();
1032        assert_eq!(got, Foo { xs: vec![1, 5, 10] });
1033    }
1034
1035    #[test]
1036    fn seq_in_struct_tail() {
1037        #[derive(Deserialize, Debug, PartialEq)]
1038        struct Foo {
1039            label: String,
1040            xs: Vec<i32>,
1041        }
1042        let got: Foo = de(&["foo", "1", "5", "10"]).unwrap();
1043        assert_eq!(got, Foo { label: "foo".into(), xs: vec![1, 5, 10] });
1044    }
1045
1046    #[test]
1047    fn map_headers() {
1048        let got: HashMap<String, i32> =
1049            de_headers(&["a", "b", "c"], &["1", "5", "10"]).unwrap();
1050        assert_eq!(got.len(), 3);
1051        assert_eq!(got["a"], 1);
1052        assert_eq!(got["b"], 5);
1053        assert_eq!(got["c"], 10);
1054    }
1055
1056    #[test]
1057    fn map_no_headers() {
1058        let got = de::<HashMap<String, i32>>(&["1", "5", "10"]);
1059        assert!(got.is_err());
1060    }
1061
1062    #[test]
1063    fn bytes() {
1064        let got: Vec<u8> = de::<BString>(&["foobar"]).unwrap().into();
1065        assert_eq!(got, b"foobar".to_vec());
1066    }
1067
1068    #[test]
1069    fn adjacent_fixed_arrays() {
1070        let got: ([u32; 2], [u32; 2]) = de(&["1", "5", "10", "15"]).unwrap();
1071        assert_eq!(got, ([1, 5], [10, 15]));
1072    }
1073
1074    #[test]
1075    fn enum_label_simple_tagged() {
1076        #[derive(Deserialize, Debug, PartialEq)]
1077        struct Row {
1078            label: Label,
1079            x: f64,
1080        }
1081
1082        #[derive(Deserialize, Debug, PartialEq)]
1083        #[serde(rename_all = "snake_case")]
1084        enum Label {
1085            Foo,
1086            Bar,
1087            Baz,
1088        }
1089
1090        let got: Row = de_headers(&["label", "x"], &["bar", "5"]).unwrap();
1091        assert_eq!(got, Row { label: Label::Bar, x: 5.0 });
1092    }
1093
1094    #[test]
1095    fn enum_untagged() {
1096        #[derive(Deserialize, Debug, PartialEq)]
1097        struct Row {
1098            x: Boolish,
1099            y: Boolish,
1100            z: Boolish,
1101        }
1102
1103        #[derive(Deserialize, Debug, PartialEq)]
1104        #[serde(rename_all = "snake_case")]
1105        #[serde(untagged)]
1106        enum Boolish {
1107            Bool(bool),
1108            Number(i64),
1109            String(String),
1110        }
1111
1112        let got: Row =
1113            de_headers(&["x", "y", "z"], &["true", "null", "1"]).unwrap();
1114        assert_eq!(
1115            got,
1116            Row {
1117                x: Boolish::Bool(true),
1118                y: Boolish::String("null".into()),
1119                z: Boolish::Number(1),
1120            }
1121        );
1122    }
1123
1124    #[test]
1125    fn option_empty_field() {
1126        #[derive(Deserialize, Debug, PartialEq)]
1127        struct Foo {
1128            a: Option<i32>,
1129            b: String,
1130            c: Option<i32>,
1131        }
1132
1133        let got: Foo =
1134            de_headers(&["a", "b", "c"], &["", "foo", "5"]).unwrap();
1135        assert_eq!(got, Foo { a: None, b: "foo".into(), c: Some(5) });
1136    }
1137
1138    #[test]
1139    fn option_invalid_field() {
1140        #[derive(Deserialize, Debug, PartialEq)]
1141        struct Foo {
1142            #[serde(deserialize_with = "crate::invalid_option")]
1143            a: Option<i32>,
1144            #[serde(deserialize_with = "crate::invalid_option")]
1145            b: Option<i32>,
1146            #[serde(deserialize_with = "crate::invalid_option")]
1147            c: Option<i32>,
1148        }
1149
1150        let got: Foo =
1151            de_headers(&["a", "b", "c"], &["xyz", "", "5"]).unwrap();
1152        assert_eq!(got, Foo { a: None, b: None, c: Some(5) });
1153    }
1154
1155    #[test]
1156    fn borrowed() {
1157        #[derive(Deserialize, Debug, PartialEq)]
1158        struct Foo<'a, 'c> {
1159            a: &'a str,
1160            b: i32,
1161            c: &'c str,
1162        }
1163
1164        let headers = StringRecord::from(vec!["a", "b", "c"]);
1165        let record = StringRecord::from(vec!["foo", "5", "bar"]);
1166        let got: Foo =
1167            deserialize_string_record(&record, Some(&headers)).unwrap();
1168        assert_eq!(got, Foo { a: "foo", b: 5, c: "bar" });
1169    }
1170
1171    #[test]
1172    fn borrowed_map() {
1173        use std::collections::HashMap;
1174
1175        let headers = StringRecord::from(vec!["a", "b", "c"]);
1176        let record = StringRecord::from(vec!["aardvark", "bee", "cat"]);
1177        let got: HashMap<&str, &str> =
1178            deserialize_string_record(&record, Some(&headers)).unwrap();
1179
1180        let expected: HashMap<&str, &str> =
1181            headers.iter().zip(&record).collect();
1182        assert_eq!(got, expected);
1183    }
1184
1185    #[test]
1186    fn borrowed_map_bytes() {
1187        use std::collections::HashMap;
1188
1189        let headers = ByteRecord::from(vec![b"a", b"\xFF", b"c"]);
1190        let record = ByteRecord::from(vec!["aardvark", "bee", "cat"]);
1191        let got: HashMap<&[u8], &[u8]> =
1192            deserialize_byte_record(&record, Some(&headers)).unwrap();
1193
1194        let expected: HashMap<&[u8], &[u8]> =
1195            headers.iter().zip(&record).collect();
1196        assert_eq!(got, expected);
1197    }
1198
1199    #[test]
1200    fn flatten() {
1201        #[derive(Deserialize, Debug, PartialEq)]
1202        struct Input {
1203            x: f64,
1204            y: f64,
1205        }
1206
1207        #[derive(Deserialize, Debug, PartialEq)]
1208        struct Properties {
1209            prop1: f64,
1210            prop2: f64,
1211        }
1212
1213        #[derive(Deserialize, Debug, PartialEq)]
1214        struct Row {
1215            #[serde(flatten)]
1216            input: Input,
1217            #[serde(flatten)]
1218            properties: Properties,
1219        }
1220
1221        let header = StringRecord::from(vec!["x", "y", "prop1", "prop2"]);
1222        let record = StringRecord::from(vec!["1", "2", "3", "4"]);
1223        let got: Row = record.deserialize(Some(&header)).unwrap();
1224        assert_eq!(
1225            got,
1226            Row {
1227                input: Input { x: 1.0, y: 2.0 },
1228                properties: Properties { prop1: 3.0, prop2: 4.0 },
1229            }
1230        );
1231    }
1232
1233    #[test]
1234    fn partially_invalid_utf8() {
1235        #[derive(Debug, Deserialize, PartialEq)]
1236        struct Row {
1237            h1: String,
1238            h2: BString,
1239            h3: String,
1240        }
1241
1242        let headers = ByteRecord::from(vec![b"h1", b"h2", b"h3"]);
1243        let record =
1244            ByteRecord::from(vec![b(b"baz"), b(b"foo\xFFbar"), b(b"quux")]);
1245        let got: Row =
1246            deserialize_byte_record(&record, Some(&headers)).unwrap();
1247        assert_eq!(
1248            got,
1249            Row {
1250                h1: "baz".to_string(),
1251                h2: BString::from(b"foo\xFFbar".to_vec()),
1252                h3: "quux".to_string(),
1253            }
1254        );
1255    }
1256}