calamine/
lib.rs

1// SPDX-License-Identifier: MIT
2//
3// Copyright 2016-2025, Johann Tuffe.
4
5#![cfg_attr(docsrs, feature(doc_cfg))]
6
7//! Rust Excel/`OpenDocument` reader
8//!
9//! # Status
10//!
11//! **calamine** is a pure Rust library to read Excel and `OpenDocument` Spreadsheet files.
12//!
13//! Read both cell values and vba project.
14//!
15//! # Examples
16//! ```
17//! use calamine::{Reader, open_workbook, Xlsx, Data};
18//!
19//! // opens a new workbook
20//! # let path = format!("{}/tests/issue3.xlsm", env!("CARGO_MANIFEST_DIR"));
21//! let mut workbook: Xlsx<_> = open_workbook(path).expect("Cannot open file");
22//!
23//! // Read whole worksheet data and provide some statistics
24//! if let Ok(range) = workbook.worksheet_range("Sheet1") {
25//!     let total_cells = range.get_size().0 * range.get_size().1;
26//!     let non_empty_cells: usize = range.used_cells().count();
27//!     println!("Found {total_cells} cells in 'Sheet1', including {non_empty_cells} non empty cells");
28//!     // alternatively, we can manually filter rows
29//!     assert_eq!(non_empty_cells, range.rows()
30//!         .flat_map(|r| r.iter().filter(|&c| c != &Data::Empty)).count());
31//! }
32//!
33//! // Check if the workbook has a vba project
34//! if let Ok(Some(vba)) = workbook.vba_project() {
35//!     let module1 = vba.get_module("Module 1").unwrap();
36//!     println!("Module 1 code:");
37//!     println!("{module1}");
38//!     for r in vba.get_references() {
39//!         if r.is_missing() {
40//!             println!("Reference {} is broken or not accessible", r.name);
41//!         }
42//!     }
43//! }
44//!
45//! // You can also get defined names definition (string representation only)
46//! for name in workbook.defined_names() {
47//!     println!("name: {}, formula: {}", name.0, name.1);
48//! }
49//!
50//! // Now get all formula!
51//! let sheets = workbook.sheet_names().to_owned();
52//! for s in sheets {
53//!     println!("found {} formula in '{}'",
54//!              workbook
55//!                 .worksheet_formula(&s)
56//!                 .expect("error while getting formula")
57//!                 .rows().flat_map(|r| r.iter().filter(|f| !f.is_empty()))
58//!                 .count(),
59//!              s);
60//! }
61//! ```
62//!
63//!
64//! # Crate Features
65//!
66//! The following is a list of the optional features supported by the `calamine`
67//! crate. They are all off by default.
68//!
69//! - `chrono`: Adds support for Chrono date/time types to the API.
70//! - `dates`: A deprecated backwards compatible synonym for the `chrono` feature.
71//! - `picture`: Adds support for reading raw data for pictures in spreadsheets.
72//!
73//! A `calamine` feature can be enabled in your `Cargo.toml` file as follows:
74//!
75//! ```bash
76//! cargo add calamine -F chrono
77//! ```
78
79#[macro_use]
80mod utils;
81
82mod auto;
83mod cfb;
84mod datatype;
85mod formats;
86mod ods;
87mod xls;
88mod xlsb;
89mod xlsx;
90
91mod de;
92mod errors;
93
94pub mod changelog;
95pub mod vba;
96
97use serde::de::{Deserialize, DeserializeOwned, Deserializer};
98use std::cmp::{max, min};
99use std::fmt;
100use std::fs::File;
101use std::io::{BufReader, Read, Seek};
102use std::ops::{Index, IndexMut};
103use std::path::Path;
104
105pub use crate::auto::{open_workbook_auto, open_workbook_auto_from_rs, Sheets};
106pub use crate::datatype::{Data, DataRef, DataType, ExcelDateTime, ExcelDateTimeType};
107pub use crate::de::{DeError, RangeDeserializer, RangeDeserializerBuilder, ToCellDeserializer};
108pub use crate::errors::Error;
109pub use crate::ods::{Ods, OdsError};
110pub use crate::xls::{Xls, XlsError, XlsOptions};
111pub use crate::xlsb::{Xlsb, XlsbError};
112pub use crate::xlsx::{Xlsx, XlsxError};
113
114use crate::vba::VbaProject;
115
116// https://msdn.microsoft.com/en-us/library/office/ff839168.aspx
117/// An enum to represent all different errors that can appear as
118/// a value in a worksheet cell
119#[derive(Debug, Clone, PartialEq)]
120pub enum CellErrorType {
121    /// Division by 0 error
122    Div0,
123    /// Unavailable value error
124    NA,
125    /// Invalid name error
126    Name,
127    /// Null value error
128    Null,
129    /// Number error
130    Num,
131    /// Invalid cell reference error
132    Ref,
133    /// Value error
134    Value,
135    /// Getting data
136    GettingData,
137}
138
139impl fmt::Display for CellErrorType {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
141        match *self {
142            CellErrorType::Div0 => write!(f, "#DIV/0!"),
143            CellErrorType::NA => write!(f, "#N/A"),
144            CellErrorType::Name => write!(f, "#NAME?"),
145            CellErrorType::Null => write!(f, "#NULL!"),
146            CellErrorType::Num => write!(f, "#NUM!"),
147            CellErrorType::Ref => write!(f, "#REF!"),
148            CellErrorType::Value => write!(f, "#VALUE!"),
149            CellErrorType::GettingData => write!(f, "#DATA!"),
150        }
151    }
152}
153
154/// Dimensions info
155#[derive(Debug, Default, PartialEq, Eq, Hash, Ord, PartialOrd, Copy, Clone)]
156pub struct Dimensions {
157    /// start: (row, col)
158    pub start: (u32, u32),
159    /// end: (row, col)
160    pub end: (u32, u32),
161}
162
163#[allow(clippy::len_without_is_empty)]
164impl Dimensions {
165    /// create dimensions info with start position and end position
166    pub fn new(start: (u32, u32), end: (u32, u32)) -> Self {
167        Self { start, end }
168    }
169    /// check if a position is in it
170    pub fn contains(&self, row: u32, col: u32) -> bool {
171        row >= self.start.0 && row <= self.end.0 && col >= self.start.1 && col <= self.end.1
172    }
173    /// len
174    pub fn len(&self) -> u64 {
175        (self.end.0 - self.start.0 + 1) as u64 * (self.end.1 - self.start.1 + 1) as u64
176    }
177}
178
179/// Common file metadata
180///
181/// Depending on file type, some extra information may be stored
182/// in the Reader implementations
183#[derive(Debug, Default)]
184pub struct Metadata {
185    sheets: Vec<Sheet>,
186    /// Map of sheet names/sheet path within zip archive
187    names: Vec<(String, String)>,
188}
189
190/// Type of sheet.
191///
192/// Only Excel formats support this. Default value for ODS is
193/// `SheetType::WorkSheet`.
194///
195/// The property is defined in the following specifications:
196///
197/// - [ECMA-376 Part 1] 12.3.2, 12.3.7 and 12.3.24.
198/// - [MS-XLS `BoundSheet`].
199/// - [MS-XLSB `ST_SheetType`].
200///
201/// [ECMA-376 Part 1]: https://www.ecma-international.org/publications-and-standards/standards/ecma-376/
202/// [MS-XLS `BoundSheet`]: https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/b9ec509a-235d-424e-871d-f8e721106501
203/// [MS-XLS `BrtBundleSh`]: https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xlsb/1edadf56-b5cd-4109-abe7-76651bbe2722
204///
205#[derive(Debug, Clone, Copy, PartialEq)]
206pub enum SheetType {
207    /// A worksheet.
208    WorkSheet,
209    /// A dialog sheet.
210    DialogSheet,
211    /// A macro sheet.
212    MacroSheet,
213    /// A chartsheet.
214    ChartSheet,
215    /// A VBA module.
216    Vba,
217}
218
219/// Type of visible sheet.
220///
221/// The property is defined in the following specifications:
222///
223/// - [ECMA-376 Part 1] 18.18.68 `ST_SheetState` (Sheet Visibility Types).
224/// - [MS-XLS `BoundSheet`].
225/// - [MS-XLSB `ST_SheetState`].
226/// - [OpenDocument v1.2] 19.471 `style:display`.
227///
228/// [ECMA-376 Part 1]: https://www.ecma-international.org/publications-and-standards/standards/ecma-376/
229/// [OpenDocument v1.2]: https://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html#property-table_display
230/// [MS-XLS `BoundSheet`]: https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/b9ec509a-235d-424e-871d-f8e721106501
231/// [MS-XLSB `ST_SheetState`]: https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xlsb/74cb1d22-b931-4bf8-997d-17517e2416e9
232///
233#[derive(Debug, Clone, Copy, PartialEq)]
234pub enum SheetVisible {
235    /// Visible
236    Visible,
237    /// Hidden
238    Hidden,
239    /// The sheet is hidden and cannot be displayed using the user interface. It is supported only by Excel formats.
240    VeryHidden,
241}
242
243/// Metadata of sheet
244#[derive(Debug, Clone, PartialEq)]
245pub struct Sheet {
246    /// Name
247    pub name: String,
248    /// Type
249    /// Only Excel formats support this. Default value for ODS is `SheetType::WorkSheet`.
250    pub typ: SheetType,
251    /// Visible
252    pub visible: SheetVisible,
253}
254
255/// Row to use as header
256/// By default, the first non-empty row is used as header
257#[derive(Debug, Default, Clone, Copy)]
258#[non_exhaustive]
259pub enum HeaderRow {
260    /// First non-empty row
261    #[default]
262    FirstNonEmptyRow,
263    /// Index of the header row
264    Row(u32),
265}
266
267// FIXME `Reader` must only be seek `Seek` for `Xls::xls`. Because of the present API this limits
268// the kinds of readers (other) data in formats can be read from.
269/// A trait to share spreadsheets reader functions across different `FileType`s
270pub trait Reader<RS>: Sized
271where
272    RS: Read + Seek,
273{
274    /// Error specific to file type
275    type Error: std::fmt::Debug + From<std::io::Error>;
276
277    /// Creates a new instance.
278    fn new(reader: RS) -> Result<Self, Self::Error>;
279
280    /// Set header row (i.e. first row to be read)
281    /// If `header_row` is `None`, the first non-empty row will be used as header row
282    fn with_header_row(&mut self, header_row: HeaderRow) -> &mut Self;
283
284    /// Gets `VbaProject`
285    fn vba_project(&mut self) -> Result<Option<VbaProject>, Self::Error>;
286
287    /// Initialize
288    fn metadata(&self) -> &Metadata;
289
290    /// Read worksheet data in corresponding worksheet path
291    fn worksheet_range(&mut self, name: &str) -> Result<Range<Data>, Self::Error>;
292
293    /// Fetch all worksheet data & paths
294    fn worksheets(&mut self) -> Vec<(String, Range<Data>)>;
295
296    /// Read worksheet formula in corresponding worksheet path
297    fn worksheet_formula(&mut self, _: &str) -> Result<Range<String>, Self::Error>;
298
299    /// Get all sheet names of this workbook, in workbook order
300    ///
301    /// # Examples
302    /// ```
303    /// use calamine::{Xlsx, open_workbook, Reader};
304    ///
305    /// # let path = format!("{}/tests/issue3.xlsm", env!("CARGO_MANIFEST_DIR"));
306    /// let mut workbook: Xlsx<_> = open_workbook(path).unwrap();
307    /// println!("Sheets: {:#?}", workbook.sheet_names());
308    /// ```
309    fn sheet_names(&self) -> Vec<String> {
310        self.metadata()
311            .sheets
312            .iter()
313            .map(|s| s.name.to_owned())
314            .collect()
315    }
316
317    /// Fetch all sheets metadata
318    fn sheets_metadata(&self) -> &[Sheet] {
319        &self.metadata().sheets
320    }
321
322    /// Get all defined names (Ranges names etc)
323    fn defined_names(&self) -> &[(String, String)] {
324        &self.metadata().names
325    }
326
327    /// Get the nth worksheet. Shortcut for getting the nth
328    /// worksheet name, then the corresponding worksheet.
329    fn worksheet_range_at(&mut self, n: usize) -> Option<Result<Range<Data>, Self::Error>> {
330        let name = self.sheet_names().get(n)?.to_string();
331        Some(self.worksheet_range(&name))
332    }
333
334    /// Get the raw data of the pictures in a workbook.
335    ///
336    /// Returns a vector of tuples containing the file extension and a buffer of
337    /// the image data.
338    ///
339    /// # Examples
340    ///
341    /// An example of getting the raw data of pictures in an spreadsheet file.
342    ///
343    /// ```
344    /// # use calamine::{open_workbook, Error, Reader, Xlsx};
345    /// #
346    /// # fn main() -> Result<(), Error> {
347    /// #     let path = "tests/picture.xlsx";
348    /// #
349    ///     // Open the workbook.
350    ///     let workbook: Xlsx<_> = open_workbook(path)?;
351    ///
352    ///     // Get the data for each picture.
353    ///     if let Some(pics) = workbook.pictures() {
354    ///         for (ext, data) in pics {
355    ///             println!("Type: '{}', Size: {} bytes", ext, data.len());
356    ///         }
357    ///     }
358    /// #
359    /// #     Ok(())
360    /// # }
361    /// #
362    /// ```
363    ///
364    /// Output:
365    ///
366    /// ```text
367    /// Type: 'jpg', Size: 20762 bytes
368    /// Type: 'png', Size: 23453 bytes
369    /// ```
370    ///
371    #[cfg(feature = "picture")]
372    #[cfg_attr(docsrs, doc(cfg(feature = "picture")))]
373    fn pictures(&self) -> Option<Vec<(String, Vec<u8>)>>;
374}
375
376/// A trait to share spreadsheets reader functions across different `FileType`s
377pub trait ReaderRef<RS>: Reader<RS>
378where
379    RS: Read + Seek,
380{
381    /// Get worksheet range where shared string values are only borrowed.
382    ///
383    /// This is implemented only for [`calamine::Xlsx`](crate::Xlsx) and [`calamine::Xlsb`](crate::Xlsb), as Xls and Ods formats
384    /// do not support lazy iteration.
385    fn worksheet_range_ref<'a>(&'a mut self, name: &str)
386        -> Result<Range<DataRef<'a>>, Self::Error>;
387
388    /// Get the nth worksheet range where shared string values are only borrowed. Shortcut for getting the nth
389    /// worksheet name, then the corresponding worksheet.
390    ///
391    /// This is implemented only for [`calamine::Xlsx`](crate::Xlsx) and [`calamine::Xlsb`](crate::Xlsb), as Xls and Ods formats
392    /// do not support lazy iteration.
393    fn worksheet_range_at_ref(
394        &mut self,
395        n: usize,
396    ) -> Option<Result<Range<DataRef<'_>>, Self::Error>> {
397        let name = self.sheet_names().get(n)?.to_string();
398        Some(self.worksheet_range_ref(&name))
399    }
400}
401
402/// Convenient function to open a file with a `BufReader<File>`.
403pub fn open_workbook<R, P>(path: P) -> Result<R, R::Error>
404where
405    R: Reader<BufReader<File>>,
406    P: AsRef<Path>,
407{
408    let file = BufReader::new(File::open(path)?);
409    R::new(file)
410}
411
412/// Convenient function to open a file with a `BufReader<File>`.
413pub fn open_workbook_from_rs<R, RS>(rs: RS) -> Result<R, R::Error>
414where
415    RS: Read + Seek,
416    R: Reader<RS>,
417{
418    R::new(rs)
419}
420
421/// A trait to constrain cells
422pub trait CellType: Default + Clone + PartialEq {}
423
424impl CellType for Data {}
425impl<'a> CellType for DataRef<'a> {}
426impl CellType for String {}
427impl CellType for usize {} // for tests
428
429// -----------------------------------------------------------------------
430// The `Cell` struct.
431// -----------------------------------------------------------------------
432
433/// A struct to hold a cell position and value.
434///
435/// A `Cell` is a fundamental worksheet type that is used to create a [`Range`].
436/// It contains a position and a value.
437///
438/// # Examples
439///
440/// An example of creating a range of `Cell`s and iterating over them.
441///
442/// ```
443/// use calamine::{Cell, Data, Range};
444///
445/// let cells = vec![
446///     Cell::new((1, 1), Data::Int(1)),
447///     Cell::new((1, 2), Data::Int(2)),
448///     Cell::new((3, 1), Data::Int(3)),
449/// ];
450///
451/// // Create a Range from the cells.
452/// let range = Range::from_sparse(cells);
453///
454/// // Iterate over the cells in the range.
455/// for (row, col, data) in range.cells() {
456///     println!("({row}, {col}): {data}");
457/// }
458///
459/// ```
460///
461/// Output:
462///
463/// ```text
464/// (0, 0): 1
465/// (0, 1): 2
466/// (1, 0):
467/// (1, 1):
468/// (2, 0): 3
469/// (2, 1):
470/// ```
471///
472#[derive(Debug, Clone)]
473pub struct Cell<T: CellType> {
474    // The position for the cell (row, column).
475    pos: (u32, u32),
476
477    // The [`CellType`] value of the cell.
478    val: T,
479}
480
481impl<T: CellType> Cell<T> {
482    /// Creates a new `Cell` instance.
483    ///
484    /// # Parameters
485    ///
486    /// - `position`: A tuple representing the cell's position in the form of
487    ///   `(row, column)`.
488    /// - `value`: The value of the cell, which must implement the [`CellType`]
489    ///   trait.
490    ///
491    /// # Examples
492    ///
493    /// An example of creating a new `Cell` instance.
494    ///
495    /// ```
496    /// use calamine::{Cell, Data};
497    ///
498    /// let cell = Cell::new((1, 2), Data::Int(42));
499    ///
500    /// assert_eq!(&Data::Int(42), cell.get_value());
501    /// ```
502    ///
503    pub fn new(position: (u32, u32), value: T) -> Cell<T> {
504        Cell {
505            pos: position,
506            val: value,
507        }
508    }
509
510    /// Gets `Cell` position.
511    ///
512    /// # Examples
513    ///
514    /// An example of getting a `Cell` position `(row, column)`.
515    ///
516    /// ```
517    /// use calamine::{Cell, Data};
518    ///
519    /// let cell = Cell::new((1, 2), Data::Int(42));
520    ///
521    /// assert_eq!((1, 2), cell.get_position());
522    /// ```
523    ///
524    pub fn get_position(&self) -> (u32, u32) {
525        self.pos
526    }
527
528    /// Gets `Cell` value.
529    ///
530    /// # Examples
531    ///
532    /// An example of getting a `Cell` value.
533    ///
534    /// ```
535    /// use calamine::{Cell, Data};
536    ///
537    /// let cell = Cell::new((1, 2), Data::Int(42));
538    ///
539    /// assert_eq!(&Data::Int(42), cell.get_value());
540    /// ```
541    ///
542    pub fn get_value(&self) -> &T {
543        &self.val
544    }
545}
546
547// -----------------------------------------------------------------------
548// The `Range` struct.
549// -----------------------------------------------------------------------
550
551/// A struct which represents an area of cells and the data within it.
552///
553/// Ranges are used by `calamine` to represent an area of data in a worksheet. A
554/// `Range` is a rectangular area of cells defined by its start and end
555/// positions.
556///
557/// A `Range` is constructed with **absolute positions** in the form of `(row,
558/// column)`. The start position for the absolute positioning is the cell `(0,
559/// 0)` or `A1`. For the example range "B3:C6", shown below, the start position
560/// is `(2, 1)` and the end position is `(5, 2)`. Within the range, the cells
561/// are indexed with **relative positions** where `(0, 0)` is the start cell. In
562/// the example below the relative positions for the start and end cells are
563/// `(0, 0)` and `(3, 1)` respectively.
564///
565/// ```text
566///  ______________________________________________________________________________
567/// |         ||                |                |                |                |
568/// |         ||       A        |       B        |       C        |       D        |
569/// |_________||________________|________________|________________|________________|
570/// |    1    ||                |                |                |                |
571/// |_________||________________|________________|________________|________________|
572/// |    2    ||                |                |                |                |
573/// |_________||________________|________________|________________|________________|
574/// |    3    ||                | (2, 1), (0, 0) |                |                |
575/// |_________||________________|________________|________________|________________|
576/// |    4    ||                |                |                |                |
577/// |_________||________________|________________|________________|________________|
578/// |    5    ||                |                |                |                |
579/// |_________||________________|________________|________________|________________|
580/// |    6    ||                |                | (5,2), (3, 1)  |                |
581/// |_________||________________|________________|________________|________________|
582/// |    7    ||                |                |                |                |
583/// |_________||________________|________________|________________|________________|
584/// |_          ___________________________________________________________________|
585///   \ Sheet1 /
586///     ------
587/// ```
588///
589/// A `Range` contains a vector of cells of of generic type `T` which implement
590/// the [`CellType`] trait. The values are stored in a row-major order.
591///
592#[derive(Debug, Default, Clone, PartialEq, Eq)]
593pub struct Range<T> {
594    start: (u32, u32),
595    end: (u32, u32),
596    inner: Vec<T>,
597}
598
599impl<T: CellType> Range<T> {
600    /// Creates a new `Range` with default values.
601    ///
602    /// Create a new [`Range`] with the given start and end positions. The
603    /// positions are in worksheet absolute coordinates, i.e. `(0, 0)` is cell `A1`.
604    ///
605    /// The range is populated with default values of type `T`.
606    ///
607    /// When possible, use the more efficient [`Range::from_sparse()`]
608    /// constructor.
609    ///
610    /// # Parameters
611    ///
612    /// - `start`: The zero indexed (row, column) tuple.
613    /// - `end`: The zero indexed (row, column) tuple.
614    ///
615    /// # Panics
616    ///
617    /// Panics if `start` > `end`.
618    ///
619    ///
620    /// # Examples
621    ///
622    /// An example of creating a new calamine `Range`.
623    ///
624    /// ```
625    /// use calamine::{Data, Range};
626    ///
627    /// // Create a 8x1 Range.
628    /// let range: Range<Data> = Range::new((2, 2), (9, 2));
629    ///
630    /// assert_eq!(range.width(), 1);
631    /// assert_eq!(range.height(), 8);
632    /// assert_eq!(range.cells().count(), 8);
633    /// assert_eq!(range.used_cells().count(), 0);
634    /// ```
635    ///
636    ///
637    #[inline]
638    pub fn new(start: (u32, u32), end: (u32, u32)) -> Range<T> {
639        assert!(start <= end, "invalid range bounds");
640        Range {
641            start,
642            end,
643            inner: vec![T::default(); ((end.0 - start.0 + 1) * (end.1 - start.1 + 1)) as usize],
644        }
645    }
646
647    /// Creates a new empty `Range`.
648    ///
649    /// Creates a new [`Range`] with start and end positions both set to `(0,
650    /// 0)` and with an empty inner vector. An empty range can be expanded by
651    /// adding data.
652    ///
653    /// # Examples
654    ///
655    /// An example of creating a new empty calamine `Range`.
656    ///
657    /// ```
658    /// use calamine::{Data, Range};
659    ///
660    /// let range: Range<Data> = Range::empty();
661    ///
662    /// assert!(range.is_empty());
663    /// ```
664    ///
665    #[inline]
666    pub fn empty() -> Range<T> {
667        Range {
668            start: (0, 0),
669            end: (0, 0),
670            inner: Vec::new(),
671        }
672    }
673
674    /// Get top left cell position of a `Range`.
675    ///
676    /// Get the top left cell position of a range in absolute `(row, column)`
677    /// coordinates.
678    ///
679    /// Returns `None` if the range is empty.
680    ///
681    /// # Examples
682    ///
683    /// An example of getting the start position of a calamine `Range`.
684    ///
685    /// ```
686    /// use calamine::{Data, Range};
687    ///
688    /// let range: Range<Data> = Range::new((2, 3), (9, 3));
689    ///
690    /// assert_eq!(range.start(), Some((2, 3)));
691    /// ```
692    ///
693    #[inline]
694    pub fn start(&self) -> Option<(u32, u32)> {
695        if self.is_empty() {
696            None
697        } else {
698            Some(self.start)
699        }
700    }
701
702    /// Get bottom right cell position of a `Range`.
703    ///
704    /// Get the bottom right cell position of a range in absolute `(row,
705    /// column)` coordinates.
706    ///
707    /// Returns `None` if the range is empty.
708    ///
709    /// # Examples
710    ///
711    /// An example of getting the end position of a calamine `Range`.
712    ///
713    /// ```
714    /// use calamine::{Data, Range};
715    ///
716    /// let range: Range<Data> = Range::new((2, 3), (9, 3));
717    ///
718    /// assert_eq!(range.end(), Some((9, 3)));
719    /// ```
720    ///
721    #[inline]
722    pub fn end(&self) -> Option<(u32, u32)> {
723        if self.is_empty() {
724            None
725        } else {
726            Some(self.end)
727        }
728    }
729
730    /// Get the column width of a `Range`.
731    ///
732    /// The width is defined as the number of columns between the start and end
733    /// positions.
734    ///
735    /// # Examples
736    ///
737    /// An example of getting the column width of a calamine `Range`.
738    ///
739    /// ```
740    /// use calamine::{Data, Range};
741    ///
742    /// let range: Range<Data> = Range::new((2, 3), (9, 3));
743    ///
744    /// assert_eq!(range.width(), 1);
745    /// ```
746    ///
747    #[inline]
748    pub fn width(&self) -> usize {
749        if self.is_empty() {
750            0
751        } else {
752            (self.end.1 - self.start.1 + 1) as usize
753        }
754    }
755
756    /// Get the row height of a `Range`.
757    ///
758    /// The height is defined as the number of rows between the start and end
759    /// positions.
760    ///
761    /// # Examples
762    ///
763    /// An example of getting the row height of a calamine `Range`.
764    ///
765    /// ```
766    /// use calamine::{Data, Range};
767    ///
768    /// let range: Range<Data> = Range::new((2, 3), (9, 3));
769    ///
770    /// assert_eq!(range.height(), 8);
771    /// ```
772    ///
773    #[inline]
774    pub fn height(&self) -> usize {
775        if self.is_empty() {
776            0
777        } else {
778            (self.end.0 - self.start.0 + 1) as usize
779        }
780    }
781
782    /// Get size of a `Range` in (height, width) format.
783    ///
784    /// # Examples
785    ///
786    /// An example of getting the (height, width) size of a calamine `Range`.
787    ///
788    /// ```
789    /// use calamine::{Data, Range};
790    ///
791    /// let range: Range<Data> = Range::new((2, 3), (9, 3));
792    ///
793    /// assert_eq!(range.get_size(), (8, 1));
794    /// ```
795    ///
796    #[inline]
797    pub fn get_size(&self) -> (usize, usize) {
798        (self.height(), self.width())
799    }
800
801    /// Check if a `Range` is empty.
802    ///
803    /// # Examples
804    ///
805    /// An example of checking if a calamine `Range` is empty.
806    ///
807    /// ```
808    /// use calamine::{Data, Range};
809    ///
810    /// let range: Range<Data> = Range::empty();
811    ///
812    /// assert!(range.is_empty());
813    /// ```
814    ///
815    #[inline]
816    pub fn is_empty(&self) -> bool {
817        self.inner.is_empty()
818    }
819
820    /// Creates a `Range` from a sparse vector of cells.
821    ///
822    /// The `Range::from_sparse()` constructor can be used to create a Range
823    /// from a vector of [`Cell`] data. This is slightly more efficient than
824    /// creating a range with [`Range::new()`] and then setting the values.
825    ///
826    /// # Parameters
827    ///
828    /// - `cells`: A vector of [`Cell`] elements.
829    ///
830    /// # Examples
831    ///
832    /// An example of creating a new calamine `Range` for a sparse vector of
833    /// Cells.
834    ///
835    /// ```
836    /// use calamine::{Cell, Data, Range};
837    ///
838    /// let cells = vec![
839    ///     Cell::new((2, 2), Data::Int(1)),
840    ///     Cell::new((5, 2), Data::Int(1)),
841    ///     Cell::new((9, 2), Data::Int(1)),
842    /// ];
843    ///
844    /// let range = Range::from_sparse(cells);
845    ///
846    /// assert_eq!(range.width(), 1);
847    /// assert_eq!(range.height(), 8);
848    /// assert_eq!(range.cells().count(), 8);
849    /// assert_eq!(range.used_cells().count(), 3);
850    /// ```
851    ///
852    pub fn from_sparse(cells: Vec<Cell<T>>) -> Range<T> {
853        if cells.is_empty() {
854            return Range::empty();
855        }
856        // cells do not always appear in (row, col) order
857        // search bounds
858        let mut row_start = u32::MAX;
859        let mut row_end = 0;
860        let mut col_start = u32::MAX;
861        let mut col_end = 0;
862        for (r, c) in cells.iter().map(|c| c.pos) {
863            row_start = min(r, row_start);
864            row_end = max(r, row_end);
865            col_start = min(c, col_start);
866            col_end = max(c, col_end);
867        }
868        let cols = (col_end - col_start + 1) as usize;
869        let rows = (row_end - row_start + 1) as usize;
870        let len = cols.saturating_mul(rows);
871        let mut v = vec![T::default(); len];
872        v.shrink_to_fit();
873        for c in cells {
874            let row = (c.pos.0 - row_start) as usize;
875            let col = (c.pos.1 - col_start) as usize;
876            let idx = row.saturating_mul(cols) + col;
877            if let Some(v) = v.get_mut(idx) {
878                *v = c.val;
879            }
880        }
881        Range {
882            start: (row_start, col_start),
883            end: (row_end, col_end),
884            inner: v,
885        }
886    }
887
888    /// Set a value at an absolute position in a `Range`.
889    ///
890    /// This method sets a value in the range at the given absolute position
891    /// (relative to `A1`).
892    ///
893    /// Try to avoid this method as much as possible and prefer initializing the
894    /// `Range` with the [`Range::from_sparse()`] constructor.
895    ///
896    /// # Parameters
897    ///
898    /// - `absolute_position`: The absolute position, relative to `A1`, in the
899    ///   form of `(row, column)`. It must be greater than or equal to the start
900    ///   position of the range. If the position is greater than the end of the range
901    ///   the structure will be resized to accommodate the new end position.
902    ///
903    /// # Panics
904    ///
905    /// If `absolute_position.0 < self.start.0 || absolute_position.1 < self.start.1`
906    ///
907    /// # Examples
908    ///
909    /// An example of setting a value in a calamine `Range`.
910    ///
911    /// ```
912    /// use calamine::{Data, Range};
913    ///
914    /// let mut range = Range::new((0, 0), (5, 2));
915    ///
916    /// // The initial range is empty.
917    /// assert_eq!(range.get_value((2, 1)), Some(&Data::Empty));
918    ///
919    /// // Set a value at a specific position.
920    /// range.set_value((2, 1), Data::Float(1.0));
921    ///
922    /// // The value at the specified position should now be set.
923    /// assert_eq!(range.get_value((2, 1)), Some(&Data::Float(1.0)));
924    /// ```
925    ///
926    pub fn set_value(&mut self, absolute_position: (u32, u32), value: T) {
927        assert!(
928            self.start.0 <= absolute_position.0 && self.start.1 <= absolute_position.1,
929            "absolute_position out of bounds"
930        );
931
932        // check if we need to change range dimension (strangely happens sometimes ...)
933        match (
934            self.end.0 < absolute_position.0,
935            self.end.1 < absolute_position.1,
936        ) {
937            (false, false) => (), // regular case, position within bounds
938            (true, false) => {
939                let len = (absolute_position.0 - self.end.0 + 1) as usize * self.width();
940                self.inner.extend_from_slice(&vec![T::default(); len]);
941                self.end.0 = absolute_position.0;
942            }
943            // missing some rows
944            (e, true) => {
945                let height = if e {
946                    (absolute_position.0 - self.start.0 + 1) as usize
947                } else {
948                    self.height()
949                };
950                let width = (absolute_position.1 - self.start.1 + 1) as usize;
951                let old_width = self.width();
952                let mut data = Vec::with_capacity(width * height);
953                let empty = vec![T::default(); width - old_width];
954                for sce in self.inner.chunks(old_width) {
955                    data.extend_from_slice(sce);
956                    data.extend_from_slice(&empty);
957                }
958                data.extend_from_slice(&vec![T::default(); width * (height - self.height())]);
959                if e {
960                    self.end = absolute_position;
961                } else {
962                    self.end.1 = absolute_position.1;
963                }
964                self.inner = data;
965            } // missing some columns
966        }
967
968        let pos = (
969            absolute_position.0 - self.start.0,
970            absolute_position.1 - self.start.1,
971        );
972        let idx = pos.0 as usize * self.width() + pos.1 as usize;
973        self.inner[idx] = value;
974    }
975
976    /// Get a value at an absolute position in a `Range`.
977    ///
978    /// If the `absolute_position` is out of range, returns `None`, otherwise
979    /// returns the cell value. The coordinate format is `(row, column)`
980    /// relative to `A1`.
981    ///
982    /// For relative positions see the [`Range::get()`] method.
983    ///
984    /// # Parameters
985    ///
986    /// - `absolute_position`: The absolute position, relative to `A1`, in the
987    ///   form of `(row, column)`.
988    ///
989    /// # Examples
990    ///
991    /// An example of getting a value in a calamine `Range`.
992    ///
993    /// ```
994    /// use calamine::{Data, Range};
995    ///
996    /// let range = Range::new((1, 1), (5, 5));
997    ///
998    /// // Get the value for a cell in the range.
999    /// assert_eq!(range.get_value((2, 2)), Some(&Data::Empty));
1000    ///
1001    /// // Get the value for a cell outside the range.
1002    /// assert_eq!(range.get_value((0, 0)), None);
1003    /// ```
1004    ///
1005    pub fn get_value(&self, absolute_position: (u32, u32)) -> Option<&T> {
1006        let p = absolute_position;
1007        if p.0 >= self.start.0 && p.0 <= self.end.0 && p.1 >= self.start.1 && p.1 <= self.end.1 {
1008            return self.get((
1009                (absolute_position.0 - self.start.0) as usize,
1010                (absolute_position.1 - self.start.1) as usize,
1011            ));
1012        }
1013        None
1014    }
1015
1016    /// Get a value at a relative position in a `Range`.
1017    ///
1018    /// If the `relative_position` is out of range, returns `None`, otherwise
1019    /// returns the cell value. The coordinate format is `(row, column)`
1020    /// relative to `(0, 0)` in the range.
1021    ///
1022    /// For absolute cell positioning see the [`Range::get_value()`] method.
1023    ///
1024    /// # Parameters
1025    ///
1026    /// - `relative_position`: The position relative to the index `(0, 0)` in
1027    ///   the range.
1028    ///
1029    /// # Examples
1030    ///
1031    /// An example of getting a value in a calamine `Range`, using relative
1032    /// positioning.
1033    ///
1034    /// ```
1035    /// use calamine::{Data, Range};
1036    ///
1037    /// let mut range = Range::new((1, 1), (5, 5));
1038    ///
1039    /// // Set a cell value using the cell absolute position.
1040    /// range.set_value((2, 3), Data::Int(123));
1041    ///
1042    /// // Get the value using the range relative position.
1043    /// assert_eq!(range.get((1, 2)), Some(&Data::Int(123)));
1044    /// ```
1045    ///
1046    pub fn get(&self, relative_position: (usize, usize)) -> Option<&T> {
1047        let (row, col) = relative_position;
1048        let (height, width) = self.get_size();
1049        if col >= width || row >= height {
1050            None
1051        } else {
1052            self.inner.get(row * width + col)
1053        }
1054    }
1055
1056    /// Get an iterator over the rows of a `Range`.
1057    ///
1058    /// # Examples
1059    ///
1060    /// An example of using a `Row` iterator with a calamine `Range`.
1061    ///
1062    /// ```
1063    /// use calamine::{Cell, Data, Range};
1064    ///
1065    /// let cells = vec![
1066    ///     Cell::new((1, 1), Data::Int(1)),
1067    ///     Cell::new((1, 2), Data::Int(2)),
1068    ///     Cell::new((3, 1), Data::Int(3)),
1069    /// ];
1070    ///
1071    /// // Create a Range from the cells.
1072    /// let range = Range::from_sparse(cells);
1073    ///
1074    /// // Iterate over the rows of the range.
1075    /// for (row_num, row) in range.rows().enumerate() {
1076    ///     for (col_num, data) in row.iter().enumerate() {
1077    ///         // Print the data in each cell of the row.
1078    ///         println!("({row_num}, {col_num}): {data}");
1079    ///     }
1080    /// }
1081    ///
1082    /// ```
1083    ///
1084    /// Output in relative coordinates:
1085    ///
1086    /// ```text
1087    /// (0, 0): 1
1088    /// (0, 1): 2
1089    /// (1, 0):
1090    /// (1, 1):
1091    /// (2, 0): 3
1092    /// (2, 1):
1093    /// ```
1094    ///
1095    pub fn rows(&self) -> Rows<'_, T> {
1096        if self.inner.is_empty() {
1097            Rows { inner: None }
1098        } else {
1099            let width = self.width();
1100            Rows {
1101                inner: Some(self.inner.chunks(width)),
1102            }
1103        }
1104    }
1105
1106    /// Get an iterator over the used cells in a `Range`.
1107    ///
1108    /// This method returns an iterator over the used cells in a range. The
1109    /// "used" cells are defined as the cells that have a value other than the
1110    /// default value for `T`. The iterator returns tuples of `(row, column,
1111    /// value)` for each used cell. The row and column are relative/index values
1112    /// rather than absolute cell positions.
1113    ///
1114    /// # Examples
1115    ///
1116    /// An example of iterating over the used cells in a calamine `Range`.
1117    ///
1118    /// ```
1119    /// use calamine::{Cell, Data, Range};
1120    ///
1121    /// let cells = vec![
1122    ///     Cell::new((1, 1), Data::Int(1)),
1123    ///     Cell::new((1, 2), Data::Int(2)),
1124    ///     Cell::new((3, 1), Data::Int(3)),
1125    /// ];
1126    ///
1127    /// // Create a Range from the cells.
1128    /// let range = Range::from_sparse(cells);
1129    ///
1130    /// // Iterate over the used cells in the range.
1131    /// for (row, col, data) in range.used_cells() {
1132    ///     println!("({row}, {col}): {data}");
1133    /// }
1134    /// ```
1135    ///
1136    /// Output:
1137    ///
1138    /// ```text
1139    /// (0, 0): 1
1140    /// (0, 1): 2
1141    /// (2, 0): 3
1142    /// ```
1143    ///
1144    pub fn used_cells(&self) -> UsedCells<'_, T> {
1145        UsedCells {
1146            width: self.width(),
1147            inner: self.inner.iter().enumerate(),
1148        }
1149    }
1150
1151    /// Get an iterator over all the cells in a `Range`.
1152    ///
1153    /// This method returns an iterator over all the cells in a range, including
1154    /// those that are empty. The iterator returns tuples of `(row, column,
1155    /// value)` for each cell. The row and column are relative/index values
1156    /// rather than absolute cell positions.
1157    ///
1158    /// # Examples
1159    ///
1160    /// An example of iterating over the used cells in a calamine `Range`.
1161    ///
1162    /// ```
1163    /// use calamine::{Cell, Data, Range};
1164    ///
1165    /// let cells = vec![
1166    ///     Cell::new((1, 1), Data::Int(1)),
1167    ///     Cell::new((1, 2), Data::Int(2)),
1168    ///     Cell::new((3, 1), Data::Int(3)),
1169    /// ];
1170    ///
1171    /// // Create a Range from the cells.
1172    /// let range = Range::from_sparse(cells);
1173    ///
1174    /// // Iterate over the cells in the range.
1175    /// for (row, col, data) in range.cells() {
1176    ///     println!("({row}, {col}): {data}");
1177    /// }
1178    /// ```
1179    ///
1180    /// Output:
1181    ///
1182    /// ```text
1183    /// (0, 0): 1
1184    /// (0, 1): 2
1185    /// (1, 0):
1186    /// (1, 1):
1187    /// (2, 0): 3
1188    /// (2, 1):
1189    /// ```
1190    ///
1191    pub fn cells(&self) -> Cells<'_, T> {
1192        Cells {
1193            width: self.width(),
1194            inner: self.inner.iter().enumerate(),
1195        }
1196    }
1197
1198    /// Build a `RangeDeserializer` for a `Range`.
1199    ///
1200    /// This method returns a [`RangeDeserializer`] that can be used to
1201    /// deserialize the data in the range.
1202    ///
1203    /// # Errors
1204    ///
1205    /// - [`DeError`] if the range cannot be deserialized.
1206    ///
1207    /// # Examples
1208    ///
1209    /// An example of creating a deserializer fora calamine `Range`.
1210    ///
1211    /// The sample Excel file `temperature.xlsx` contains a single sheet named
1212    /// "Sheet1" with the following data:
1213    ///
1214    /// ```text
1215    ///  ____________________________________________
1216    /// |         ||                |                |
1217    /// |         ||       A        |       B        |
1218    /// |_________||________________|________________|
1219    /// |    1    || label          | value          |
1220    /// |_________||________________|________________|
1221    /// |    2    || celsius        | 22.2222        |
1222    /// |_________||________________|________________|
1223    /// |    3    || fahrenheit     | 72             |
1224    /// |_________||________________|________________|
1225    /// |_          _________________________________|
1226    ///   \ Sheet1 /
1227    ///     ------
1228    /// ```
1229    ///
1230    /// ```
1231    /// use calamine::{open_workbook, Error, Reader, Xlsx};
1232    ///
1233    /// fn main() -> Result<(), Error> {
1234    ///     let path = "tests/temperature.xlsx";
1235    ///
1236    ///     // Open the workbook.
1237    ///     let mut workbook: Xlsx<_> = open_workbook(path)?;
1238    ///
1239    ///     // Get the data range from the first sheet.
1240    ///     let sheet_range = workbook.worksheet_range("Sheet1")?;
1241    ///
1242    ///     // Get an iterator over data in the range.
1243    ///     let mut iter = sheet_range.deserialize()?;
1244    ///
1245    ///     // Get the next record in the range. The first row is assumed to be the
1246    ///     // header.
1247    ///     if let Some(result) = iter.next() {
1248    ///         let (label, value): (String, f64) = result?;
1249    ///
1250    ///         assert_eq!(label, "celsius");
1251    ///         assert_eq!(value, 22.2222);
1252    ///
1253    ///         Ok(())
1254    ///     } else {
1255    ///         Err(From::from("Expected at least one record but got none"))
1256    ///     }
1257    /// }
1258    /// ```
1259    ///
1260    pub fn deserialize<'a, D>(&'a self) -> Result<RangeDeserializer<'a, T, D>, DeError>
1261    where
1262        T: ToCellDeserializer<'a>,
1263        D: DeserializeOwned,
1264    {
1265        RangeDeserializerBuilder::new().from_range(self)
1266    }
1267
1268    /// Build a new `Range` out of the current range.
1269    ///
1270    /// This method returns a new `Range` with cloned data. In general it is
1271    /// used to get a subset of an existing range. However, if the new range is
1272    /// larger than the existing range the new cells will be filled with default
1273    /// values.
1274    ///
1275    /// # Examples
1276    ///
1277    /// An example of getting a sub range of a calamine `Range`.
1278    ///
1279    /// ```
1280    /// use calamine::{Data, Range};
1281    ///
1282    /// // Create a range with some values.
1283    /// let mut a = Range::new((1, 1), (3, 3));
1284    /// a.set_value((1, 1), Data::Bool(true));
1285    /// a.set_value((2, 2), Data::Bool(true));
1286    /// a.set_value((3, 3), Data::Bool(true));
1287    ///
1288    /// // Get a sub range of the main range.
1289    /// let b = a.range((1, 1), (2, 2));
1290    /// assert_eq!(b.get_value((1, 1)), Some(&Data::Bool(true)));
1291    /// assert_eq!(b.get_value((2, 2)), Some(&Data::Bool(true)));
1292    ///
1293    /// // Get a larger range with default values.
1294    /// let c = a.range((0, 0), (5, 5));
1295    /// assert_eq!(c.get_value((0, 0)), Some(&Data::Empty));
1296    /// assert_eq!(c.get_value((3, 3)), Some(&Data::Bool(true)));
1297    /// assert_eq!(c.get_value((5, 5)), Some(&Data::Empty));
1298    /// ```
1299    ///
1300    pub fn range(&self, start: (u32, u32), end: (u32, u32)) -> Range<T> {
1301        let mut other = Range::new(start, end);
1302        let (self_start_row, self_start_col) = self.start;
1303        let (self_end_row, self_end_col) = self.end;
1304        let (other_start_row, other_start_col) = other.start;
1305        let (other_end_row, other_end_col) = other.end;
1306
1307        // copy data from self to other
1308        let start_row = max(self_start_row, other_start_row);
1309        let end_row = min(self_end_row, other_end_row);
1310        let start_col = max(self_start_col, other_start_col);
1311        let end_col = min(self_end_col, other_end_col);
1312
1313        if start_row > end_row || start_col > end_col {
1314            return other;
1315        }
1316
1317        let self_width = self.width();
1318        let other_width = other.width();
1319
1320        // change referential
1321        //
1322        // we want to copy range: start_row..(end_row + 1)
1323        // In self referential it is (start_row - self_start_row)..(end_row + 1 - self_start_row)
1324        let self_row_start = (start_row - self_start_row) as usize;
1325        let self_row_end = (end_row + 1 - self_start_row) as usize;
1326        let self_col_start = (start_col - self_start_col) as usize;
1327        let self_col_end = (end_col + 1 - self_start_col) as usize;
1328
1329        let other_row_start = (start_row - other_start_row) as usize;
1330        let other_row_end = (end_row + 1 - other_start_row) as usize;
1331        let other_col_start = (start_col - other_start_col) as usize;
1332        let other_col_end = (end_col + 1 - other_start_col) as usize;
1333
1334        {
1335            let self_rows = self
1336                .inner
1337                .chunks(self_width)
1338                .take(self_row_end)
1339                .skip(self_row_start);
1340
1341            let other_rows = other
1342                .inner
1343                .chunks_mut(other_width)
1344                .take(other_row_end)
1345                .skip(other_row_start);
1346
1347            for (self_row, other_row) in self_rows.zip(other_rows) {
1348                let self_cols = &self_row[self_col_start..self_col_end];
1349                let other_cols = &mut other_row[other_col_start..other_col_end];
1350                other_cols.clone_from_slice(self_cols);
1351            }
1352        }
1353
1354        other
1355    }
1356}
1357
1358impl<T: CellType + fmt::Display> Range<T> {
1359    /// Get headers for a `Range`.
1360    ///
1361    /// This method returns the first row of the range as an optional vector of
1362    /// strings. The data type `T` in the range must support the [`ToString`]
1363    /// trait.
1364    ///
1365    /// # Examples
1366    ///
1367    /// An example of getting the header row of a calamine `Range`.
1368    ///
1369    /// ```
1370    /// use calamine::{Data, Range};
1371    ///
1372    /// // Create a range with some values.
1373    /// let mut range = Range::new((0, 0), (5, 2));
1374    /// range.set_value((0, 0), Data::String(String::from("a")));
1375    /// range.set_value((0, 1), Data::Int(1));
1376    /// range.set_value((0, 2), Data::Bool(true));
1377    ///
1378    /// // Get the headers of the range.
1379    /// let headers = range.headers();
1380    ///
1381    /// assert_eq!(
1382    ///     headers,
1383    ///     Some(vec![
1384    ///         String::from("a"),
1385    ///         String::from("1"),
1386    ///         String::from("true")
1387    ///     ])
1388    /// );
1389    /// ```
1390    ///
1391    pub fn headers(&self) -> Option<Vec<String>> {
1392        self.rows()
1393            .next()
1394            .map(|row| row.iter().map(ToString::to_string).collect())
1395    }
1396}
1397
1398/// Implementation of the `Index` trait for `Range` rows.
1399///
1400/// # Examples
1401///
1402/// An example of row indexing for a calamine `Range`.
1403///
1404/// ```
1405/// use calamine::{Data, Range};
1406///
1407/// // Create a range with a value.
1408/// let mut range = Range::new((1, 1), (3, 3));
1409/// range.set_value((2, 2), Data::Int(123));
1410///
1411/// // Get the second row via indexing.
1412/// assert_eq!(range[1], [Data::Empty, Data::Int(123), Data::Empty]);
1413/// ```
1414///
1415impl<T: CellType> Index<usize> for Range<T> {
1416    type Output = [T];
1417    fn index(&self, index: usize) -> &[T] {
1418        let width = self.width();
1419        &self.inner[index * width..(index + 1) * width]
1420    }
1421}
1422
1423/// Implementation of the `Index` trait for `Range` cells.
1424///
1425/// # Examples
1426///
1427/// An example of cell indexing for a calamine `Range`.
1428///
1429/// ```
1430/// use calamine::{Data, Range};
1431///
1432/// // Create a range with a value.
1433/// let mut range = Range::new((1, 1), (3, 3));
1434/// range.set_value((2, 2), Data::Int(123));
1435///
1436/// // Get the value via cell indexing.
1437/// assert_eq!(range[(1, 1)], Data::Int(123));
1438/// ```
1439///
1440impl<T: CellType> Index<(usize, usize)> for Range<T> {
1441    type Output = T;
1442    fn index(&self, index: (usize, usize)) -> &T {
1443        let (height, width) = self.get_size();
1444        assert!(index.1 < width && index.0 < height, "index out of bounds");
1445        &self.inner[index.0 * width + index.1]
1446    }
1447}
1448
1449/// Implementation of the `IndexMut` trait for `Range` rows.
1450impl<T: CellType> IndexMut<usize> for Range<T> {
1451    fn index_mut(&mut self, index: usize) -> &mut [T] {
1452        let width = self.width();
1453        &mut self.inner[index * width..(index + 1) * width]
1454    }
1455}
1456
1457/// Implementation of the `IndexMut` trait for `Range` cells.
1458///
1459/// # Examples
1460///
1461/// An example of mutable cell indexing for a calamine `Range`.
1462///
1463/// ```
1464/// use calamine::{Data, Range};
1465///
1466/// // Create a new empty range.
1467/// let mut range = Range::new((1, 1), (3, 3));
1468///
1469/// // Set a value in the range using cell indexing.
1470/// range[(1, 1)] = Data::Int(123);
1471///
1472/// // Test the value was set correctly.
1473/// assert_eq!(range.get((1, 1)), Some(&Data::Int(123)));
1474/// ```
1475///
1476impl<T: CellType> IndexMut<(usize, usize)> for Range<T> {
1477    fn index_mut(&mut self, index: (usize, usize)) -> &mut T {
1478        let (height, width) = self.get_size();
1479        assert!(index.1 < width && index.0 < height, "index out of bounds");
1480        &mut self.inner[index.0 * width + index.1]
1481    }
1482}
1483
1484// -----------------------------------------------------------------------
1485// Range Iterators.
1486// -----------------------------------------------------------------------
1487
1488/// A struct to iterate over all `Cell`s in a `Range`.
1489///
1490/// # Examples
1491///
1492/// An example iterating over the cells in a calamine range using the `Cells`
1493/// iterator returned by [`Range::cells()`].
1494///
1495/// ```
1496/// use calamine::{Cell, Data, Range};
1497///
1498/// let cells = vec![
1499///     Cell::new((1, 1), Data::Int(1)),
1500///     Cell::new((1, 2), Data::Int(2)),
1501///     Cell::new((3, 1), Data::Int(3)),
1502/// ];
1503///
1504/// // Create a Range from the cells.
1505/// let range = Range::from_sparse(cells);
1506///
1507/// // Use the Cells iterator returned by Range::cells().
1508/// for (row, col, data) in range.cells() {
1509///     println!("({row}, {col}): {data}");
1510/// }
1511///
1512/// ```
1513///
1514/// Output:
1515///
1516/// ```text
1517/// (0, 0): 1
1518/// (0, 1): 2
1519/// (1, 0):
1520/// (1, 1):
1521/// (2, 0): 3
1522/// (2, 1):
1523/// ```
1524///
1525#[derive(Clone, Debug)]
1526pub struct Cells<'a, T: CellType> {
1527    width: usize,
1528    inner: std::iter::Enumerate<std::slice::Iter<'a, T>>,
1529}
1530
1531impl<'a, T: 'a + CellType> Iterator for Cells<'a, T> {
1532    type Item = (usize, usize, &'a T);
1533    fn next(&mut self) -> Option<Self::Item> {
1534        self.inner.next().map(|(i, v)| {
1535            let row = i / self.width;
1536            let col = i % self.width;
1537            (row, col, v)
1538        })
1539    }
1540    fn size_hint(&self) -> (usize, Option<usize>) {
1541        self.inner.size_hint()
1542    }
1543}
1544
1545impl<'a, T: 'a + CellType> DoubleEndedIterator for Cells<'a, T> {
1546    fn next_back(&mut self) -> Option<Self::Item> {
1547        self.inner.next_back().map(|(i, v)| {
1548            let row = i / self.width;
1549            let col = i % self.width;
1550            (row, col, v)
1551        })
1552    }
1553}
1554
1555impl<'a, T: 'a + CellType> ExactSizeIterator for Cells<'a, T> {}
1556
1557/// A struct to iterate over all the used `Cell`s in a `Range`.
1558///
1559/// # Examples
1560///
1561/// An example iterating over the used cells in a calamine range using the
1562/// `UsedCells` iterator returned by [`Range::used_cells()`].
1563///
1564/// ```
1565/// use calamine::{Cell, Data, Range};
1566///
1567/// let cells = vec![
1568///     Cell::new((1, 1), Data::Int(1)),
1569///     Cell::new((1, 2), Data::Int(2)),
1570///     Cell::new((3, 1), Data::Int(3)),
1571/// ];
1572///
1573/// // Create a Range from the cells.
1574/// let range = Range::from_sparse(cells);
1575///
1576/// // Use the UsedCells iterator returned by Range::used_cells().
1577/// for (row, col, data) in range.used_cells() {
1578///     println!("({row}, {col}): {data}");
1579/// }
1580///
1581/// ```
1582///
1583/// Output:
1584///
1585/// ```text
1586/// (0, 0): 1
1587/// (0, 1): 2
1588/// (2, 0): 3
1589/// ```
1590///
1591#[derive(Clone, Debug)]
1592pub struct UsedCells<'a, T: CellType> {
1593    width: usize,
1594    inner: std::iter::Enumerate<std::slice::Iter<'a, T>>,
1595}
1596
1597impl<'a, T: 'a + CellType> Iterator for UsedCells<'a, T> {
1598    type Item = (usize, usize, &'a T);
1599    fn next(&mut self) -> Option<Self::Item> {
1600        self.inner
1601            .by_ref()
1602            .find(|&(_, v)| v != &T::default())
1603            .map(|(i, v)| {
1604                let row = i / self.width;
1605                let col = i % self.width;
1606                (row, col, v)
1607            })
1608    }
1609    fn size_hint(&self) -> (usize, Option<usize>) {
1610        let (_, up) = self.inner.size_hint();
1611        (0, up)
1612    }
1613}
1614
1615impl<'a, T: 'a + CellType> DoubleEndedIterator for UsedCells<'a, T> {
1616    fn next_back(&mut self) -> Option<Self::Item> {
1617        self.inner
1618            .by_ref()
1619            .rfind(|&(_, v)| v != &T::default())
1620            .map(|(i, v)| {
1621                let row = i / self.width;
1622                let col = i % self.width;
1623                (row, col, v)
1624            })
1625    }
1626}
1627
1628/// A struct to iterate over all `Rows`s in a `Range`.
1629///
1630/// # Examples
1631///
1632/// An example iterating over the rows in a calamine range using the `Rows`
1633/// iterator returned by [`Range::rows()`].
1634///
1635/// ```
1636/// use calamine::{Cell, Data, Range};
1637///
1638/// let cells = vec![
1639///     Cell::new((1, 1), Data::Int(1)),
1640///     Cell::new((1, 2), Data::Int(2)),
1641///     Cell::new((3, 1), Data::Int(3)),
1642/// ];
1643///
1644/// // Create a Range from the cells.
1645/// let range = Range::from_sparse(cells);
1646///
1647/// // Use the Rows iterator returned by Range::rows().
1648/// for (row_num, row) in range.rows().enumerate() {
1649///     for (col_num, data) in row.iter().enumerate() {
1650///         // Print the data in each cell of the row.
1651///         println!("({row_num}, {col_num}): {data}");
1652///     }
1653/// }
1654/// ```
1655///
1656/// Output in relative coordinates:
1657///
1658/// ```text
1659/// (0, 0): 1
1660/// (0, 1): 2
1661/// (1, 0):
1662/// (1, 1):
1663/// (2, 0): 3
1664/// (2, 1):
1665/// ```
1666///
1667#[derive(Clone, Debug)]
1668pub struct Rows<'a, T: CellType> {
1669    inner: Option<std::slice::Chunks<'a, T>>,
1670}
1671
1672impl<'a, T: 'a + CellType> Iterator for Rows<'a, T> {
1673    type Item = &'a [T];
1674    fn next(&mut self) -> Option<Self::Item> {
1675        self.inner.as_mut().and_then(std::iter::Iterator::next)
1676    }
1677    fn size_hint(&self) -> (usize, Option<usize>) {
1678        self.inner
1679            .as_ref()
1680            .map_or((0, Some(0)), std::iter::Iterator::size_hint)
1681    }
1682}
1683
1684impl<'a, T: 'a + CellType> DoubleEndedIterator for Rows<'a, T> {
1685    fn next_back(&mut self) -> Option<Self::Item> {
1686        self.inner
1687            .as_mut()
1688            .and_then(std::iter::DoubleEndedIterator::next_back)
1689    }
1690}
1691
1692impl<'a, T: 'a + CellType> ExactSizeIterator for Rows<'a, T> {}
1693
1694// -----------------------------------------------------------------------
1695// The `Table` struct.
1696// -----------------------------------------------------------------------
1697
1698/// The `Table` struct represents an Excel worksheet table.
1699///
1700/// Tables in Excel are a way of grouping a range of cells into a single entity
1701/// that has common formatting or that can be referenced in formulas. In
1702/// `calamine`, tables can be read and converted to a data [`Range`] for further
1703/// processing.
1704///
1705/// Calamine does not automatically load Table data from a workbook to avoid
1706/// unnecessary overhead. Instead you must explicitly load the Table data using
1707/// the [`Xlsx::load_tables()`](crate::Xlsx::load_tables) method. Once the
1708/// tables have been loaded the following methods can be used to extract and
1709/// work with individual tables:
1710///
1711/// - [`Xlsx::table_by_name()`](crate::Xlsx::table_by_name).
1712/// - [`Xlsx::table_by_name_ref()`](crate::Xlsx::table_by_name_ref).
1713/// - [`Xlsx::table_names()`](crate::Xlsx::table_names).
1714/// - [`Xlsx::table_names_in_sheet()`](crate::Xlsx::table_names_in_sheet).
1715///
1716/// Note, these methods are only available for the [`Xlsx`] struct since Tables
1717/// are a feature of the xlsx/xlsb format. They are not currently implemented
1718/// for [`Xlsb`].
1719///
1720/// Once you have a `Table` instance, you can access its properties and data
1721/// using the methods below.
1722///
1723/// # Examples
1724///
1725/// An example of reading the data from an Excel worksheet Table using the
1726/// `calamine` crate.
1727///
1728/// The sample Excel file `inventory-table.xlsx` contains a single sheet named
1729/// "Sheet1" with the following data laid out in a worksheet Table called
1730/// "Table1":
1731///
1732/// ```text
1733///  _____________________________________________________________
1734/// |         ||                |                |                |
1735/// |         ||       A        |       B        |       C        |
1736/// |_________||________________|________________|________________|
1737/// |    1    || Item           | Type           | Quantity       |
1738/// |_________||________________|________________|________________|
1739/// |    2    ||              1 | Apple          |             50 |
1740/// |_________||________________|________________|________________|
1741/// |    3    ||              2 | Banana         |            200 |
1742/// |_________||________________|________________|________________|
1743/// |    4    ||              3 | Orange         |             60 |
1744/// |_________||________________|________________|________________|
1745/// |    5    ||              4 | Pear           |            100 |
1746/// |_________||________________|________________|________________|
1747/// |_          __________________________________________________|
1748///   \ Sheet1 /
1749///     ------
1750/// ```
1751///
1752/// ```
1753/// use calamine::{open_workbook, Error, Xlsx};
1754///
1755/// fn main() -> Result<(), Error> {
1756///     let path = format!("{}/tests/inventory-table.xlsx", env!("CARGO_MANIFEST_DIR"));
1757///
1758///     // Open the workbook.
1759///     let mut workbook: Xlsx<_> = open_workbook(path)?;
1760///
1761///     // Load the tables in the workbook.
1762///     workbook.load_tables()?;
1763///
1764///     // Get the table by name.
1765///     let table = workbook.table_by_name("Table1")?;
1766///
1767///     // Check the table's name.
1768///     let table_name = table.name();
1769///     assert_eq!(table_name, "Table1");
1770///
1771///     // Check that it came from Sheet1.
1772///     let sheet_name = table.sheet_name();
1773///     assert_eq!(sheet_name, "Sheet1");
1774///
1775///     // Get the table column headers.
1776///     let columns_headers = table.columns();
1777///     assert_eq!(columns_headers, vec!["Item", "Type", "Quantity"]);
1778///
1779///     // Get the table data range (without the headers).
1780///     let data = table.data();
1781///
1782///     // Iterate over the rows of the data range.
1783///     for (row_num, row) in data.rows().enumerate() {
1784///         for (col_num, data) in row.iter().enumerate() {
1785///             // Print the data in each cell of the row.
1786///             println!("({row_num}, {col_num}): {data}");
1787///         }
1788///         println!();
1789///     }
1790///
1791///     Ok(())
1792/// }
1793/// ```
1794///
1795/// Output in relative coordinates:
1796///
1797/// ```text
1798/// (0, 0): 1
1799/// (0, 1): Apple
1800/// (0, 2): 50
1801///
1802/// (1, 0): 2
1803/// (1, 1): Banana
1804/// (1, 2): 200
1805///
1806/// (2, 0): 3
1807/// (2, 1): Orange
1808/// (2, 2): 60
1809///
1810/// (3, 0): 4
1811/// (3, 1): Pear
1812/// (3, 2): 100
1813/// ```
1814///
1815#[derive(Debug, Clone)]
1816pub struct Table<T> {
1817    pub(crate) name: String,
1818    pub(crate) sheet_name: String,
1819    pub(crate) columns: Vec<String>,
1820    pub(crate) data: Range<T>,
1821}
1822impl<T> Table<T> {
1823    /// Get the name of the table.
1824    ///
1825    /// Tables in Excel have sequentially assigned names like "Table1",
1826    /// "Table2", etc. but can also have used assigned names.
1827    ///
1828    /// # Examples
1829    ///
1830    /// An example of getting the name of an Excel worksheet Table.
1831    ///
1832    /// ```
1833    /// use calamine::{open_workbook, Error, Xlsx};
1834    ///
1835    /// fn main() -> Result<(), Error> {
1836    ///     let path = format!("{}/tests/inventory-table.xlsx", env!("CARGO_MANIFEST_DIR"));
1837    ///
1838    ///     // Open the workbook.
1839    ///     let mut workbook: Xlsx<_> = open_workbook(path)?;
1840    ///
1841    ///     // Load the tables in the workbook.
1842    ///     workbook.load_tables()?;
1843    ///
1844    ///     // Get the table by name.
1845    ///     let table = workbook.table_by_name("Table1")?;
1846    ///
1847    ///     // Check the table's name.
1848    ///     let table_name = table.name();
1849    ///     assert_eq!(table_name, "Table1");
1850    ///
1851    ///     Ok(())
1852    /// }
1853    /// ```
1854    ///
1855    pub fn name(&self) -> &str {
1856        &self.name
1857    }
1858    /// Get the name of the parent worksheet for a table.
1859    ///
1860    /// This method returns the name of the parent worksheet that contains the
1861    /// table.
1862    ///
1863    /// # Examples
1864    ///
1865    /// An example of getting the parent worksheet name for an Excel worksheet
1866    /// Table.
1867    ///
1868    /// ```
1869    /// use calamine::{open_workbook, Error, Xlsx};
1870    ///
1871    /// fn main() -> Result<(), Error> {
1872    ///     let path = format!("{}/tests/inventory-table.xlsx", env!("CARGO_MANIFEST_DIR"));
1873    ///
1874    ///     // Open the workbook.
1875    ///     let mut workbook: Xlsx<_> = open_workbook(path)?;
1876    ///
1877    ///     // Load the tables in the workbook.
1878    ///     workbook.load_tables()?;
1879    ///
1880    ///     // Get the table by name.
1881    ///     let table = workbook.table_by_name("Table1")?;
1882    ///
1883    ///     // Check that it came from Sheet1.
1884    ///     let sheet_name = table.sheet_name();
1885    ///     assert_eq!(sheet_name, "Sheet1");
1886    ///
1887    ///     Ok(())
1888    /// }
1889    /// ```
1890    ///
1891    pub fn sheet_name(&self) -> &str {
1892        &self.sheet_name
1893    }
1894
1895    /// Get the header names of the table columns.
1896    ///
1897    /// This method returns a slice of strings representing the names of the
1898    /// column headers in the table.
1899    ///
1900    /// In Excel table headers can be hidden but the table will still have
1901    /// column header names.
1902    ///
1903    /// # Examples
1904    ///
1905    /// An example of getting the column headers for an Excel worksheet Table.
1906    ///
1907    /// ```
1908    /// use calamine::{open_workbook, Error, Xlsx};
1909    ///
1910    /// fn main() -> Result<(), Error> {
1911    ///     let path = format!("{}/tests/inventory-table.xlsx", env!("CARGO_MANIFEST_DIR"));
1912    ///
1913    ///     // Open the workbook.
1914    ///     let mut workbook: Xlsx<_> = open_workbook(path)?;
1915    ///
1916    ///     // Load the tables in the workbook.
1917    ///     workbook.load_tables()?;
1918    ///
1919    ///     // Get the table by name.
1920    ///     let table = workbook.table_by_name("Table1")?;
1921    ///
1922    ///     // Get the table column headers.
1923    ///     let columns_headers = table.columns();
1924    ///     assert_eq!(columns_headers, vec!["Item", "Type", "Quantity"]);
1925    ///
1926    ///     Ok(())
1927    /// }
1928    /// ```
1929    ///
1930    pub fn columns(&self) -> &[String] {
1931        &self.columns
1932    }
1933
1934    /// Get a range representing the data from the table
1935    ///
1936    /// This method returns a reference to the data [`Range`] of the table,
1937    ///
1938    /// Note that the data range excludes the column headers.
1939    ///
1940    /// # Examples
1941    ///
1942    /// An example of getting the data range of an Excel worksheet Table.
1943    ///
1944    /// ```
1945    /// use calamine::{open_workbook, Data, Error, Xlsx};
1946    ///
1947    /// fn main() -> Result<(), Error> {
1948    ///     let path = format!("{}/tests/inventory-table.xlsx", env!("CARGO_MANIFEST_DIR"));
1949    ///
1950    ///     // Open the workbook.
1951    ///     let mut workbook: Xlsx<_> = open_workbook(path)?;
1952    ///
1953    ///     // Load the tables in the workbook.
1954    ///     workbook.load_tables()?;
1955    ///
1956    ///     // Get the table by name.
1957    ///     let table = workbook.table_by_name("Table1")?;
1958    ///
1959    ///     // Get the data range of the table.
1960    ///     let data_range = table.data();
1961    ///
1962    ///     // Check one of the values in the data range. Note the relative
1963    ///     // positioning within the range returned by the `get()` method.
1964    ///     assert_eq!(
1965    ///         data_range.get((0, 1)),
1966    ///         Some(&Data::String("Apple".to_string()))
1967    ///     );
1968    ///
1969    ///     Ok(())
1970    /// }
1971    /// ```
1972    ///
1973    pub fn data(&self) -> &Range<T> {
1974        &self.data
1975    }
1976}
1977
1978/// Convert a `Table<T>` into a `Range<T>`.
1979///
1980/// # Examples
1981///
1982/// An example of getting the data range of an Excel worksheet Table via the
1983/// `From/Into` trait.
1984///
1985/// ```
1986/// use calamine::{open_workbook, Data, Error, Range, Xlsx};
1987///
1988/// fn main() -> Result<(), Error> {
1989///     let path = format!("{}/tests/inventory-table.xlsx", env!("CARGO_MANIFEST_DIR"));
1990///
1991///     // Open the workbook.
1992///     let mut workbook: Xlsx<_> = open_workbook(path)?;
1993///
1994///     // Load the tables in the workbook.
1995///     workbook.load_tables()?;
1996///
1997///     // Get the table by name.
1998///     let table = workbook.table_by_name("Table1")?;
1999///
2000///     // Convert the table into a data range using the `From/Into` trait.
2001///     let data_range: Range<Data> = table.into();
2002///
2003///     // Check one of the values in the data range. Note the relative
2004///     // positioning within the range returned by the `get()` method.
2005///     assert_eq!(
2006///         data_range.get((0, 1)),
2007///         Some(&Data::String("Apple".to_string()))
2008///     );
2009///
2010///     Ok(())
2011/// }
2012/// ```
2013///
2014impl<T: CellType> From<Table<T>> for Range<T> {
2015    fn from(table: Table<T>) -> Range<T> {
2016        table.data
2017    }
2018}
2019
2020/// A helper function to deserialize cell values as `i64`.
2021///
2022/// This is useful when cells may also contain invalid values (i.e. strings). It
2023/// applies the [`as_i64`](crate::datatype::DataType::as_i64) method to the cell
2024/// value, and returns `Ok(Some(value_as_i64))` if successful or `Ok(None)` if
2025/// unsuccessful, therefore never failing.
2026///
2027/// This function is intended to be used with Serde's
2028/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2029/// field attribute.
2030///
2031pub fn deserialize_as_i64_or_none<'de, D>(deserializer: D) -> Result<Option<i64>, D::Error>
2032where
2033    D: Deserializer<'de>,
2034{
2035    let data = Data::deserialize(deserializer)?;
2036    Ok(data.as_i64())
2037}
2038
2039/// A helper function to deserialize cell values as `i64`.
2040///
2041/// This is useful when cells may also contain invalid values (i.e. strings). It
2042/// applies the [`as_i64`](crate::datatype::DataType::as_i64) method to the cell
2043/// value, and returns `Ok(Ok(value_as_i64))` if successful or
2044/// `Ok(Err(value_to_string))` if unsuccessful, therefore never failing.
2045///
2046/// This function is intended to be used with Serde's
2047/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2048/// field attribute.
2049///
2050pub fn deserialize_as_i64_or_string<'de, D>(
2051    deserializer: D,
2052) -> Result<Result<i64, String>, D::Error>
2053where
2054    D: Deserializer<'de>,
2055{
2056    let data = Data::deserialize(deserializer)?;
2057    Ok(data.as_i64().ok_or_else(|| data.to_string()))
2058}
2059
2060/// A helper function to deserialize cell values as `f64`.
2061///
2062/// This is useful when cells may also contain invalid values (i.e. strings). It
2063/// applies the [`as_f64`](crate::datatype::DataType::as_f64) method to the cell
2064/// value, and returns `Ok(Some(value_as_f64))` if successful or `Ok(None)` if
2065/// unsuccessful, therefore never failing.
2066///
2067/// This function is intended to be used with Serde's
2068/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2069/// field attribute.
2070///
2071pub fn deserialize_as_f64_or_none<'de, D>(deserializer: D) -> Result<Option<f64>, D::Error>
2072where
2073    D: Deserializer<'de>,
2074{
2075    let data = Data::deserialize(deserializer)?;
2076    Ok(data.as_f64())
2077}
2078
2079/// A helper function to deserialize cell values as `f64`.
2080///
2081/// This is useful when cells may also contain invalid values (i.e. strings). It
2082/// applies the [`as_f64`](crate::datatype::DataType::as_f64) method to the cell
2083/// value, and returns `Ok(Ok(value_as_f64))` if successful or
2084/// `Ok(Err(value_to_string))` if unsuccessful, therefore never failing.
2085///
2086/// This function is intended to be used with Serde's
2087/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2088/// field attribute.
2089///
2090pub fn deserialize_as_f64_or_string<'de, D>(
2091    deserializer: D,
2092) -> Result<Result<f64, String>, D::Error>
2093where
2094    D: Deserializer<'de>,
2095{
2096    let data = Data::deserialize(deserializer)?;
2097    Ok(data.as_f64().ok_or_else(|| data.to_string()))
2098}
2099
2100/// A helper function to deserialize cell values as [`chrono::NaiveDate`].
2101///
2102/// This is useful when cells may also contain invalid values (i.e. strings). It
2103/// applies the [`as_date()`](crate::Data::as_date) method to the cell value,
2104/// and returns `Ok(Some(value_as_date))` if successful or `Ok(None)` if
2105/// unsuccessful, therefore never failing.
2106///
2107/// This function is intended to be used with Serde's
2108/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2109/// field attribute.
2110///
2111/// [`chrono::NaiveDate`]: https://docs.rs/chrono/latest/chrono/naive/struct.NaiveDate.html
2112///
2113#[cfg(feature = "chrono")]
2114#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
2115pub fn deserialize_as_date_or_none<'de, D>(
2116    deserializer: D,
2117) -> Result<Option<chrono::NaiveDate>, D::Error>
2118where
2119    D: Deserializer<'de>,
2120{
2121    let data = Data::deserialize(deserializer)?;
2122    Ok(data.as_date())
2123}
2124
2125/// A helper function to deserialize cell values as [`chrono::NaiveDate`].
2126///
2127/// This is useful when cells may also contain invalid values (i.e. strings). It
2128/// applies the [`as_date()`](crate::Data::as_date) method to the cell value,
2129/// and returns `Ok(Ok(value_as_date))` if successful or
2130/// `Ok(Err(value_to_string))` if unsuccessful, therefore never failing.
2131///
2132/// This function is intended to be used with Serde's
2133/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2134/// field attribute.
2135///
2136/// [`chrono::NaiveDate`]: https://docs.rs/chrono/latest/chrono/naive/struct.NaiveDate.html
2137///
2138#[cfg(feature = "chrono")]
2139#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
2140pub fn deserialize_as_date_or_string<'de, D>(
2141    deserializer: D,
2142) -> Result<Result<chrono::NaiveDate, String>, D::Error>
2143where
2144    D: Deserializer<'de>,
2145{
2146    let data = Data::deserialize(deserializer)?;
2147    Ok(data.as_date().ok_or_else(|| data.to_string()))
2148}
2149
2150/// A helper function to deserialize cell values as [`chrono::NaiveTime`].
2151///
2152/// This is useful when cells may also contain invalid values (i.e. strings). It
2153/// applies the [`as_time()`](crate::Data::as_time) method to the cell value,
2154/// and returns `Ok(Some(value_as_time))` if successful or `Ok(None)` if
2155/// unsuccessful, therefore never failing.
2156///
2157/// This function is intended to be used with Serde's
2158/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2159/// field attribute.
2160///
2161/// [`chrono::NaiveTime`]:
2162///     https://docs.rs/chrono/latest/chrono/naive/struct.NaiveTime.html
2163///
2164#[cfg(feature = "chrono")]
2165#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
2166pub fn deserialize_as_time_or_none<'de, D>(
2167    deserializer: D,
2168) -> Result<Option<chrono::NaiveTime>, D::Error>
2169where
2170    D: Deserializer<'de>,
2171{
2172    let data = Data::deserialize(deserializer)?;
2173    Ok(data.as_time())
2174}
2175
2176/// A helper function to deserialize cell values as [`chrono::NaiveTime`].
2177///
2178/// This is useful when cells may also contain invalid values (i.e. strings). It
2179/// applies the [`as_time()`](crate::Data::as_time) method to the cell value,
2180/// and returns `Ok(Ok(value_as_time))` if successful or
2181/// `Ok(Err(value_to_string))` if unsuccessful, therefore never failing.
2182///
2183/// This function is intended to be used with Serde's
2184/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2185/// field attribute.
2186///
2187/// [`chrono::NaiveTime`]:
2188///     https://docs.rs/chrono/latest/chrono/naive/struct.NaiveTime.html
2189///
2190#[cfg(feature = "chrono")]
2191#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
2192pub fn deserialize_as_time_or_string<'de, D>(
2193    deserializer: D,
2194) -> Result<Result<chrono::NaiveTime, String>, D::Error>
2195where
2196    D: Deserializer<'de>,
2197{
2198    let data = Data::deserialize(deserializer)?;
2199    Ok(data.as_time().ok_or_else(|| data.to_string()))
2200}
2201
2202/// A helper function to deserialize cell values as [`chrono::Duration`].
2203///
2204/// This is useful when cells may also contain invalid values (i.e. strings). It
2205/// applies the [`as_duration()`](crate::Data::as_duration) method to the cell
2206/// value, and returns `Ok(Some(value_as_duration))` if successful or `Ok(None)`
2207/// if unsuccessful, therefore never failing.
2208///
2209/// This function is intended to be used with Serde's
2210/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2211/// field attribute.
2212///
2213/// [`chrono::Duration`]:
2214///     https://docs.rs/chrono/latest/chrono/struct.Duration.html
2215///
2216#[cfg(feature = "chrono")]
2217#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
2218pub fn deserialize_as_duration_or_none<'de, D>(
2219    deserializer: D,
2220) -> Result<Option<chrono::Duration>, D::Error>
2221where
2222    D: Deserializer<'de>,
2223{
2224    let data = Data::deserialize(deserializer)?;
2225    Ok(data.as_duration())
2226}
2227
2228/// A helper function to deserialize cell values as [`chrono::Duration`].
2229///
2230/// This is useful when cells may also contain invalid values (i.e. strings). It
2231/// applies the [`as_duration()`](crate::Data::as_duration) method to the cell
2232/// value, and returns `Ok(Ok(value_as_duration))` if successful or
2233/// `Ok(Err(value_to_string))` if unsuccessful, therefore never failing.
2234///
2235/// This function is intended to be used with Serde's
2236/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2237/// field attribute.
2238///
2239/// [`chrono::Duration`]:
2240///     https://docs.rs/chrono/latest/chrono/struct.Duration.html
2241///
2242#[cfg(feature = "chrono")]
2243#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
2244pub fn deserialize_as_duration_or_string<'de, D>(
2245    deserializer: D,
2246) -> Result<Result<chrono::Duration, String>, D::Error>
2247where
2248    D: Deserializer<'de>,
2249{
2250    let data = Data::deserialize(deserializer)?;
2251    Ok(data.as_duration().ok_or_else(|| data.to_string()))
2252}
2253
2254/// A helper function to deserialize cell values as [`chrono::NaiveDateTime`].
2255///
2256/// This is useful when cells may also contain invalid values (i.e. strings). It
2257/// applies the [`as_datetime()`](crate::Data::as_datetime) method to the cell
2258/// value, and returns `Ok(Some(value_as_datetime))` if successful or `Ok(None)`
2259/// if unsuccessful, therefore never failing.
2260///
2261/// This function is intended to be used with Serde's
2262/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2263/// field attribute.
2264///
2265/// [`chrono::NaiveDateTime`]:
2266///     https://docs.rs/chrono/latest/chrono/naive/struct.NaiveDateTime.html
2267///
2268#[cfg(feature = "chrono")]
2269#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
2270pub fn deserialize_as_datetime_or_none<'de, D>(
2271    deserializer: D,
2272) -> Result<Option<chrono::NaiveDateTime>, D::Error>
2273where
2274    D: Deserializer<'de>,
2275{
2276    let data = Data::deserialize(deserializer)?;
2277    Ok(data.as_datetime())
2278}
2279
2280/// A helper function to deserialize cell values as [`chrono::NaiveDateTime`].
2281///
2282/// This is useful when cells may also contain invalid values (i.e. strings). It
2283/// applies the [`as_datetime()`](crate::Data::as_datetime) method to the cell
2284/// value, and returns `Ok(Ok(value_as_datetime))` if successful or
2285/// `Ok(Err(value_to_string))` if unsuccessful, therefore never failing.
2286///
2287/// This function is intended to be used with Serde's
2288/// [`deserialize_with`](https://serde.rs/field-attrs.html#deserialize_with)
2289/// field attribute.
2290///
2291/// [`chrono::NaiveDateTime`]:
2292///     https://docs.rs/chrono/latest/chrono/naive/struct.NaiveDateTime.html
2293///
2294#[cfg(feature = "chrono")]
2295#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
2296pub fn deserialize_as_datetime_or_string<'de, D>(
2297    deserializer: D,
2298) -> Result<Result<chrono::NaiveDateTime, String>, D::Error>
2299where
2300    D: Deserializer<'de>,
2301{
2302    let data = Data::deserialize(deserializer)?;
2303    Ok(data.as_datetime().ok_or_else(|| data.to_string()))
2304}