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
60trait DeRecord<'r> {
77 fn has_headers(&self) -> bool;
79
80 fn next_header(&mut self) -> Result<Option<&'r str>, DeserializeError>;
82
83 fn next_header_bytes(
85 &mut self,
86 ) -> Result<Option<&'r [u8]>, DeserializeError>;
87
88 fn next_field(&mut self) -> Result<&'r str, DeserializeError>;
90
91 fn next_field_bytes(&mut self) -> Result<&'r [u8], DeserializeError>;
93
94 fn peek_field(&mut self) -> Option<&'r [u8]>;
96
97 fn error(&self, kind: DeserializeErrorKind) -> DeserializeError;
99
100 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 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 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#[derive(Clone, Debug, Eq, PartialEq)]
666pub struct DeserializeError {
667 field: Option<u64>,
668 kind: DeserializeErrorKind,
669}
670
671#[derive(Clone, Debug, Eq, PartialEq)]
673pub enum DeserializeErrorKind {
674 Message(String),
676 Unsupported(String),
678 UnexpectedEndOfRow,
681 InvalidUtf8(str::Utf8Error),
685 ParseBool(str::ParseBoolError),
687 ParseInt(num::ParseIntError),
689 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 pub fn field(&self) -> Option<u64> {
736 self.field
737 }
738
739 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}