calamine/
de.rs

1use serde::de::value::BorrowedStrDeserializer;
2use serde::de::{self, DeserializeOwned, DeserializeSeed, SeqAccess, Visitor};
3use serde::{self, forward_to_deserialize_any, Deserialize};
4use std::marker::PhantomData;
5use std::{fmt, slice, str};
6
7use super::{CellErrorType, CellType, DataType, Range, Rows};
8
9/// A cell deserialization specific error enum
10#[derive(Debug)]
11pub enum DeError {
12    /// Cell out of range
13    CellOutOfRange {
14        /// Position tried
15        try_pos: (u32, u32),
16        /// Minimum position
17        min_pos: (u32, u32),
18    },
19    /// The cell value is an error
20    CellError {
21        /// Cell value error
22        err: CellErrorType,
23        /// Cell position
24        pos: (u32, u32),
25    },
26    /// Unexpected end of row
27    UnexpectedEndOfRow {
28        /// Cell position
29        pos: (u32, u32),
30    },
31    /// Required header not found
32    HeaderNotFound(String),
33    /// Serde specific error
34    Custom(String),
35}
36
37impl fmt::Display for DeError {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
39        match *self {
40            DeError::CellOutOfRange {
41                ref try_pos,
42                ref min_pos,
43            } => write!(
44                f,
45                "there is no cell at position '{:?}'.Minimum position is '{:?}'",
46                try_pos, min_pos
47            ),
48            DeError::CellError { ref pos, ref err } => {
49                write!(f, "Cell error at position '{:?}': {}", pos, err)
50            }
51            DeError::UnexpectedEndOfRow { ref pos } => {
52                write!(f, "Unexpected end of row at position '{:?}'", pos)
53            }
54            DeError::HeaderNotFound(ref header) => {
55                write!(f, "Cannot find header named '{}'", header)
56            }
57            DeError::Custom(ref s) => write!(f, "{}", s),
58        }
59    }
60}
61
62impl std::error::Error for DeError {
63    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
64        None
65    }
66}
67
68impl de::Error for DeError {
69    fn custom<T: fmt::Display>(msg: T) -> Self {
70        DeError::Custom(msg.to_string())
71    }
72}
73
74#[derive(Clone)]
75pub enum Headers<'h, H> {
76    None,
77    All,
78    Custom(&'h [H]),
79}
80
81/// Builds a `Range` deserializer with some configuration options.
82///
83/// This can be used to optionally parse the first row as a header. Once built,
84/// a `RangeDeserializer`s cannot be changed.
85#[derive(Clone)]
86pub struct RangeDeserializerBuilder<'h, H> {
87    headers: Headers<'h, H>,
88}
89
90impl Default for RangeDeserializerBuilder<'static, &'static str> {
91    fn default() -> Self {
92        RangeDeserializerBuilder {
93            headers: Headers::All,
94        }
95    }
96}
97
98impl RangeDeserializerBuilder<'static, &'static str> {
99    /// Constructs a new builder for configuring `Range` deserialization.
100    pub fn new() -> Self {
101        Default::default()
102    }
103
104    /// Decide whether to treat the first row as a special header row.
105    ///
106    /// # Example
107    ///
108    /// ```
109    /// # use calamine::{DataType, Error, open_workbook, Xlsx, Reader, RangeDeserializerBuilder};
110    /// fn main() -> Result<(), Error> {
111    ///     let path = format!("{}/tests/temperature.xlsx", env!("CARGO_MANIFEST_DIR"));
112    ///     let mut workbook: Xlsx<_> = open_workbook(path)?;
113    ///     let range = workbook.worksheet_range("Sheet1")
114    ///         .ok_or(Error::Msg("Cannot find 'Sheet1'"))??;
115    ///
116    ///     let mut iter = RangeDeserializerBuilder::new()
117    ///         .has_headers(false)
118    ///         .from_range(&range)?;
119    ///
120    ///     if let Some(result) = iter.next() {
121    ///         let row: Vec<DataType> = result?;
122    ///         assert_eq!(row, [DataType::from("label"), DataType::from("value")]);
123    ///     } else {
124    ///         return Err(From::from("expected at least three records but got none"));
125    ///     }
126    ///
127    ///     if let Some(result) = iter.next() {
128    ///         let row: Vec<DataType> = result?;
129    ///         assert_eq!(row, [DataType::from("celsius"), DataType::from(22.2222)]);
130    ///     } else {
131    ///         return Err(From::from("expected at least three records but got one"));
132    ///     }
133    ///
134    ///     Ok(())
135    /// }
136    /// ```
137    pub fn has_headers(&mut self, yes: bool) -> &mut Self {
138        if yes {
139            self.headers = Headers::All;
140        } else {
141            self.headers = Headers::None;
142        }
143        self
144    }
145}
146
147impl<'h, H: AsRef<str> + Clone + 'h> RangeDeserializerBuilder<'h, H> {
148    /// Build a `RangeDeserializer` from this configuration and keep only selected headers.
149    ///
150    /// # Example
151    ///
152    /// ```
153    /// # use calamine::{open_workbook, Error, Xlsx, Reader, RangeDeserializerBuilder};
154    /// fn main() -> Result<(), Error> {
155    ///     let path = format!("{}/tests/temperature.xlsx", env!("CARGO_MANIFEST_DIR"));
156    ///     let mut workbook: Xlsx<_> = open_workbook(path)?;
157    ///     let range = workbook.worksheet_range("Sheet1")
158    ///         .ok_or(Error::Msg("Cannot find 'Sheet1'"))??;
159    ///     let mut iter = RangeDeserializerBuilder::with_headers(&["value", "label"]).from_range(&range)?;
160    ///
161    ///     if let Some(result) = iter.next() {
162    ///         let (value, label): (f64, String) = result?;
163    ///         assert_eq!(label, "celsius");
164    ///         assert_eq!(value, 22.2222);
165    ///
166    ///         Ok(())
167    ///     } else {
168    ///         return Err(From::from("expected at least one record but got none"));
169    ///     }
170    /// }
171    /// ```
172    pub fn with_headers(headers: &'h [H]) -> Self {
173        RangeDeserializerBuilder {
174            headers: Headers::Custom(headers),
175        }
176    }
177
178    /// Build a `RangeDeserializer` from this configuration.
179    ///
180    /// # Example
181    ///
182    /// ```
183    /// # use calamine::{open_workbook, Error, Xlsx, Reader, RangeDeserializerBuilder};
184    /// fn main() -> Result<(), Error> {
185    ///     let path = format!("{}/tests/temperature.xlsx", env!("CARGO_MANIFEST_DIR"));
186    ///     let mut workbook: Xlsx<_> = open_workbook(path)?;
187    ///     let range = workbook.worksheet_range("Sheet1")
188    ///         .ok_or(Error::Msg("Cannot find 'Sheet1'"))??;
189    ///     let mut iter = RangeDeserializerBuilder::new().from_range(&range)?;
190    ///
191    ///     if let Some(result) = iter.next() {
192    ///         let (label, value): (String, f64) = result?;
193    ///         assert_eq!(label, "celsius");
194    ///         assert_eq!(value, 22.2222);
195    ///
196    ///         Ok(())
197    ///     } else {
198    ///         return Err(From::from("expected at least one record but got none"));
199    ///     }
200    /// }
201    /// ```
202    pub fn from_range<'cell, T, D>(
203        &self,
204        range: &'cell Range<T>,
205    ) -> Result<RangeDeserializer<'cell, T, D>, DeError>
206    where
207        T: ToCellDeserializer<'cell>,
208        D: DeserializeOwned,
209    {
210        RangeDeserializer::new(self, range)
211    }
212}
213
214/// A configured `Range` deserializer.
215///
216/// # Example
217///
218/// ```
219/// # use calamine::{open_workbook, Error, Xlsx, Reader, RangeDeserializerBuilder};
220/// fn main() -> Result<(), Error> {
221///     let path = format!("{}/tests/temperature.xlsx", env!("CARGO_MANIFEST_DIR"));
222///     let mut workbook: Xlsx<_> = open_workbook(path)?;
223///     let range = workbook.worksheet_range("Sheet1")
224///         .ok_or(Error::Msg("Cannot find 'Sheet1'"))??;
225///
226///     let mut iter = RangeDeserializerBuilder::new().from_range(&range)?;
227///
228///     if let Some(result) = iter.next() {
229///         let (label, value): (String, f64) = result?;
230///         assert_eq!(label, "celsius");
231///         assert_eq!(value, 22.2222);
232///         Ok(())
233///     } else {
234///         Err(From::from("expected at least one record but got none"))
235///     }
236/// }
237/// ```
238pub struct RangeDeserializer<'cell, T, D>
239where
240    T: ToCellDeserializer<'cell>,
241    D: DeserializeOwned,
242{
243    column_indexes: Vec<usize>,
244    headers: Option<Vec<String>>,
245    rows: Rows<'cell, T>,
246    current_pos: (u32, u32),
247    end_pos: (u32, u32),
248    _priv: PhantomData<D>,
249}
250
251impl<'cell, T, D> RangeDeserializer<'cell, T, D>
252where
253    T: ToCellDeserializer<'cell>,
254    D: DeserializeOwned,
255{
256    fn new<'h, H: AsRef<str> + Clone + 'h>(
257        builder: &RangeDeserializerBuilder<'h, H>,
258        range: &'cell Range<T>,
259    ) -> Result<Self, DeError> {
260        let mut rows = range.rows();
261
262        let mut current_pos = range.start().unwrap_or((0, 0));
263        let end_pos = range.end().unwrap_or((0, 0));
264
265        let (column_indexes, headers) = match builder.headers {
266            Headers::None => ((0..range.width()).collect(), None),
267            Headers::All => {
268                if let Some(row) = rows.next() {
269                    let all_indexes = (0..row.len()).collect::<Vec<_>>();
270                    let all_headers = {
271                        let de = RowDeserializer::new(&all_indexes, None, row, current_pos);
272                        current_pos.0 += 1;
273                        Deserialize::deserialize(de)?
274                    };
275                    (all_indexes, Some(all_headers))
276                } else {
277                    (Vec::new(), None)
278                }
279            }
280            Headers::Custom(headers) => {
281                if let Some(row) = rows.next() {
282                    let all_indexes = (0..row.len()).collect::<Vec<_>>();
283                    let de = RowDeserializer::new(&all_indexes, None, row, current_pos);
284                    current_pos.0 += 1;
285                    let all_headers: Vec<String> = Deserialize::deserialize(de)?;
286                    let custom_indexes = headers
287                        .iter()
288                        .map(|h| h.as_ref().trim())
289                        .map(|h| {
290                            all_headers
291                                .iter()
292                                .position(|header| header.trim() == h)
293                                .ok_or_else(|| DeError::HeaderNotFound(h.to_owned()))
294                        })
295                        .collect::<Result<Vec<_>, DeError>>()?;
296                    (custom_indexes, Some(all_headers))
297                } else {
298                    (Vec::new(), None)
299                }
300            }
301        };
302
303        Ok(RangeDeserializer {
304            column_indexes,
305            headers,
306            rows,
307            current_pos,
308            end_pos,
309            _priv: PhantomData,
310        })
311    }
312}
313
314impl<'cell, T, D> Iterator for RangeDeserializer<'cell, T, D>
315where
316    T: ToCellDeserializer<'cell>,
317    D: DeserializeOwned,
318{
319    type Item = Result<D, DeError>;
320
321    fn next(&mut self) -> Option<Self::Item> {
322        let RangeDeserializer {
323            ref column_indexes,
324            ref headers,
325            ref mut rows,
326            mut current_pos,
327            ..
328        } = *self;
329
330        if let Some(row) = rows.next() {
331            current_pos.0 += 1;
332            let headers = headers.as_ref().map(|h| &**h);
333            let de = RowDeserializer::new(column_indexes, headers, row, current_pos);
334            Some(Deserialize::deserialize(de))
335        } else {
336            None
337        }
338    }
339
340    fn size_hint(&self) -> (usize, Option<usize>) {
341        let remaining = (self.end_pos.0 - self.current_pos.0) as usize;
342
343        (remaining, Some(remaining))
344    }
345}
346
347struct RowDeserializer<'header, 'cell, T> {
348    cells: &'cell [T],
349    headers: Option<&'header [String]>,
350    iter: slice::Iter<'header, usize>, // iterator over column indexes
351    peek: Option<usize>,
352    pos: (u32, u32),
353}
354
355impl<'header, 'cell, T> RowDeserializer<'header, 'cell, T>
356where
357    T: 'cell + ToCellDeserializer<'cell>,
358{
359    fn new(
360        column_indexes: &'header [usize],
361        headers: Option<&'header [String]>,
362        cells: &'cell [T],
363        pos: (u32, u32),
364    ) -> Self {
365        RowDeserializer {
366            iter: column_indexes.iter(),
367            headers,
368            cells,
369            pos,
370            peek: None,
371        }
372    }
373
374    fn has_headers(&self) -> bool {
375        self.headers.is_some()
376    }
377}
378
379impl<'de, 'header, 'cell, T> serde::Deserializer<'de> for RowDeserializer<'header, 'cell, T>
380where
381    'header: 'de,
382    'cell: 'de,
383    T: 'cell + ToCellDeserializer<'cell>,
384{
385    type Error = DeError;
386
387    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
388    where
389        V: Visitor<'de>,
390    {
391        visitor.visit_seq(self)
392    }
393
394    fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
395        if self.has_headers() {
396            visitor.visit_map(self)
397        } else {
398            visitor.visit_seq(self)
399        }
400    }
401
402    fn deserialize_struct<V: Visitor<'de>>(
403        self,
404        _name: &'static str,
405        _cells: &'static [&'static str],
406        visitor: V,
407    ) -> Result<V::Value, Self::Error> {
408        if self.has_headers() {
409            visitor.visit_map(self)
410        } else {
411            visitor.visit_seq(self)
412        }
413    }
414
415    forward_to_deserialize_any! {
416        bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
417        byte_buf option unit unit_struct newtype_struct seq tuple
418        tuple_struct enum identifier ignored_any
419    }
420}
421
422impl<'de, 'header, 'cell, T> SeqAccess<'de> for RowDeserializer<'header, 'cell, T>
423where
424    'header: 'de,
425    'cell: 'de,
426    T: ToCellDeserializer<'cell>,
427{
428    type Error = DeError;
429
430    fn next_element_seed<D>(&mut self, seed: D) -> Result<Option<D::Value>, Self::Error>
431    where
432        D: DeserializeSeed<'de>,
433    {
434        match self.iter.next().map(|i| &self.cells[*i]) {
435            Some(value) => {
436                let de = value.to_cell_deserializer(self.pos);
437                seed.deserialize(de).map(Some)
438            }
439            None => Ok(None),
440        }
441    }
442
443    fn size_hint(&self) -> Option<usize> {
444        match self.iter.size_hint() {
445            (lower, Some(upper)) if lower == upper => Some(upper),
446            _ => None,
447        }
448    }
449}
450
451impl<'de, 'header: 'de, 'cell: 'de, T> de::MapAccess<'de> for RowDeserializer<'header, 'cell, T>
452where
453    'header: 'de,
454    'cell: 'de,
455    T: ToCellDeserializer<'cell>,
456{
457    type Error = DeError;
458
459    fn next_key_seed<K: DeserializeSeed<'de>>(
460        &mut self,
461        seed: K,
462    ) -> Result<Option<K::Value>, Self::Error> {
463        let headers = self
464            .headers
465            .expect("Cannot map-deserialize range without headers");
466
467        for i in self.iter.by_ref() {
468            if !self.cells[*i].is_empty() {
469                self.peek = Some(*i);
470                let de = BorrowedStrDeserializer::<Self::Error>::new(&headers[*i]);
471                return seed.deserialize(de).map(Some);
472            }
473        }
474        Ok(None)
475    }
476
477    fn next_value_seed<K: DeserializeSeed<'de>>(
478        &mut self,
479        seed: K,
480    ) -> Result<K::Value, Self::Error> {
481        let cell = self
482            .peek
483            .take()
484            .map(|i| &self.cells[i])
485            .ok_or(DeError::UnexpectedEndOfRow { pos: self.pos })?;
486        let de = cell.to_cell_deserializer(self.pos);
487        seed.deserialize(de)
488    }
489}
490
491/// Constructs a deserializer for a `CellType`.
492pub trait ToCellDeserializer<'a>: CellType {
493    /// The deserializer.
494    type Deserializer: for<'de> serde::Deserializer<'de, Error = DeError>;
495
496    /// Construct a `CellType` deserializer at the specified position.
497    fn to_cell_deserializer(&'a self, pos: (u32, u32)) -> Self::Deserializer;
498
499    /// Assess if the cell is empty.
500    fn is_empty(&self) -> bool;
501}
502
503impl<'a> ToCellDeserializer<'a> for DataType {
504    type Deserializer = DataTypeDeserializer<'a>;
505
506    fn to_cell_deserializer(&'a self, pos: (u32, u32)) -> DataTypeDeserializer<'a> {
507        DataTypeDeserializer {
508            data_type: self,
509            pos,
510        }
511    }
512
513    #[inline]
514    fn is_empty(&self) -> bool {
515        matches!(self, DataType::Empty)
516    }
517}
518
519macro_rules! deserialize_num {
520    ($typ:ty, $method:ident, $visit:ident) => {
521        fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
522        where
523            V: Visitor<'de>,
524        {
525            match self.data_type {
526                DataType::Float(v) => visitor.$visit(*v as $typ),
527                DataType::Int(v) => visitor.$visit(*v as $typ),
528                DataType::String(ref s) => {
529                    let v = s.parse().map_err(|_| {
530                        DeError::Custom(format!("Expecting {}, got '{}'", stringify!($typ), s))
531                    })?;
532                    visitor.$visit(v)
533                }
534                DataType::Error(ref err) => Err(DeError::CellError {
535                    err: err.clone(),
536                    pos: self.pos,
537                }),
538                ref d => Err(DeError::Custom(format!(
539                    "Expecting {}, got {:?}",
540                    stringify!($typ),
541                    d
542                ))),
543            }
544        }
545    };
546}
547
548/// A deserializer for the `DataType` type.
549pub struct DataTypeDeserializer<'a> {
550    data_type: &'a DataType,
551    pos: (u32, u32),
552}
553
554impl<'a, 'de> serde::Deserializer<'de> for DataTypeDeserializer<'a> {
555    type Error = DeError;
556
557    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
558    where
559        V: Visitor<'de>,
560    {
561        match self.data_type {
562            DataType::String(v) => visitor.visit_str(v),
563            DataType::Float(v) => visitor.visit_f64(*v),
564            DataType::Bool(v) => visitor.visit_bool(*v),
565            DataType::Int(v) => visitor.visit_i64(*v),
566            DataType::Empty => visitor.visit_unit(),
567            DataType::DateTime(v) => visitor.visit_f64(*v),
568            DataType::Duration(v) => visitor.visit_f64(*v),
569            DataType::DateTimeIso(v) => visitor.visit_str(v),
570            DataType::DurationIso(v) => visitor.visit_str(v),
571            DataType::Error(ref err) => Err(DeError::CellError {
572                err: err.clone(),
573                pos: self.pos,
574            }),
575        }
576    }
577
578    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
579    where
580        V: Visitor<'de>,
581    {
582        match self.data_type {
583            DataType::String(v) => visitor.visit_str(v),
584            DataType::Empty => visitor.visit_str(""),
585            DataType::Float(v) => visitor.visit_str(&v.to_string()),
586            DataType::Int(v) => visitor.visit_str(&v.to_string()),
587            DataType::Bool(v) => visitor.visit_str(&v.to_string()),
588            DataType::DateTime(v) => visitor.visit_str(&v.to_string()),
589            DataType::Duration(v) => visitor.visit_str(&v.to_string()),
590            DataType::DateTimeIso(v) => visitor.visit_str(v),
591            DataType::DurationIso(v) => visitor.visit_str(v),
592            DataType::Error(ref err) => Err(DeError::CellError {
593                err: err.clone(),
594                pos: self.pos,
595            }),
596        }
597    }
598
599    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
600    where
601        V: Visitor<'de>,
602    {
603        match self.data_type {
604            DataType::String(v) => visitor.visit_bytes(v.as_bytes()),
605            DataType::Empty => visitor.visit_bytes(&[]),
606            DataType::Error(ref err) => Err(DeError::CellError {
607                err: err.clone(),
608                pos: self.pos,
609            }),
610            ref d => Err(DeError::Custom(format!("Expecting bytes, got {:?}", d))),
611        }
612    }
613
614    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
615    where
616        V: Visitor<'de>,
617    {
618        self.deserialize_bytes(visitor)
619    }
620
621    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
622    where
623        V: Visitor<'de>,
624    {
625        self.deserialize_str(visitor)
626    }
627
628    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
629    where
630        V: Visitor<'de>,
631    {
632        match self.data_type {
633            DataType::Bool(v) => visitor.visit_bool(*v),
634            DataType::String(ref v) => match &**v {
635                "TRUE" | "true" | "True" => visitor.visit_bool(true),
636                "FALSE" | "false" | "False" => visitor.visit_bool(false),
637                d => Err(DeError::Custom(format!("Expecting bool, got '{}'", d))),
638            },
639            DataType::Empty => visitor.visit_bool(false),
640            DataType::Float(v) => visitor.visit_bool(*v != 0.),
641            DataType::Int(v) => visitor.visit_bool(*v != 0),
642            DataType::DateTime(v) => visitor.visit_bool(*v != 0.),
643            DataType::Duration(v) => visitor.visit_bool(*v != 0.),
644            DataType::DateTimeIso(_) => visitor.visit_bool(true),
645            DataType::DurationIso(_) => visitor.visit_bool(true),
646            DataType::Error(ref err) => Err(DeError::CellError {
647                err: err.clone(),
648                pos: self.pos,
649            }),
650        }
651    }
652
653    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
654    where
655        V: Visitor<'de>,
656    {
657        match self.data_type {
658            DataType::String(ref s) if s.len() == 1 => {
659                visitor.visit_char(s.chars().next().expect("s not empty"))
660            }
661            DataType::Error(ref err) => Err(DeError::CellError {
662                err: err.clone(),
663                pos: self.pos,
664            }),
665            ref d => Err(DeError::Custom(format!("Expecting unit, got {:?}", d))),
666        }
667    }
668
669    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
670    where
671        V: Visitor<'de>,
672    {
673        match self.data_type {
674            DataType::Empty => visitor.visit_unit(),
675            DataType::Error(ref err) => Err(DeError::CellError {
676                err: err.clone(),
677                pos: self.pos,
678            }),
679            ref d => Err(DeError::Custom(format!("Expecting unit, got {:?}", d))),
680        }
681    }
682
683    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
684    where
685        V: Visitor<'de>,
686    {
687        match self.data_type {
688            DataType::Empty => visitor.visit_none(),
689            _ => visitor.visit_some(self),
690        }
691    }
692
693    fn deserialize_newtype_struct<V>(
694        self,
695        _name: &'static str,
696        visitor: V,
697    ) -> Result<V::Value, Self::Error>
698    where
699        V: Visitor<'de>,
700    {
701        visitor.visit_newtype_struct(self)
702    }
703
704    fn deserialize_enum<V>(
705        self,
706        _name: &'static str,
707        _variants: &'static [&'static str],
708        visitor: V,
709    ) -> Result<V::Value, Self::Error>
710    where
711        V: Visitor<'de>,
712    {
713        use serde::de::IntoDeserializer;
714
715        match self.data_type {
716            DataType::String(s) => visitor.visit_enum(s.as_str().into_deserializer()),
717            DataType::Error(ref err) => Err(DeError::CellError {
718                err: err.clone(),
719                pos: self.pos,
720            }),
721            ref d => Err(DeError::Custom(format!("Expecting enum, got {:?}", d))),
722        }
723    }
724
725    deserialize_num!(i64, deserialize_i64, visit_i64);
726    deserialize_num!(i32, deserialize_i32, visit_i32);
727    deserialize_num!(i16, deserialize_i16, visit_i16);
728    deserialize_num!(i8, deserialize_i8, visit_i8);
729    deserialize_num!(u64, deserialize_u64, visit_u64);
730    deserialize_num!(u32, deserialize_u32, visit_u32);
731    deserialize_num!(u16, deserialize_u16, visit_u16);
732    deserialize_num!(u8, deserialize_u8, visit_u8);
733    deserialize_num!(f64, deserialize_f64, visit_f64);
734    deserialize_num!(f32, deserialize_f32, visit_f32);
735
736    forward_to_deserialize_any! {
737        unit_struct seq tuple tuple_struct map struct identifier ignored_any
738    }
739}
740
741#[cfg(test)]
742mod tests {
743    #[test]
744    fn test_deserialize_enum() {
745        use crate::ToCellDeserializer;
746        use serde::Deserialize;
747
748        #[derive(Debug, serde_derive::Deserialize, PartialEq)]
749        enum Content {
750            Foo,
751        }
752
753        assert_eq!(
754            Content::deserialize(
755                super::DataType::String("Foo".to_string()).to_cell_deserializer((0, 0))
756            )
757            .unwrap(),
758            Content::Foo
759        );
760    }
761}