Skip to main content

calamine_styles/
de.rs

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