Skip to main content

calamine_styles/
lib.rs

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