Skip to main content

calamine/
lib.rs

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