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