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