Skip to content

Commit

Permalink
support DataTypeRef for shared strings
Browse files Browse the repository at this point in the history
  • Loading branch information
tafia committed Oct 28, 2023
1 parent c66195c commit 1271ef1
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 87 deletions.
47 changes: 47 additions & 0 deletions src/datatype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,53 @@ where
}
}

/// An enum to represent all different data types that can appear as
/// a value in a worksheet cell
#[derive(Debug, Clone, PartialEq, Default)]
pub enum DataTypeRef<'a> {
/// Signed integer
Int(i64),
/// Float
Float(f64),
/// String
String(String),
/// Shared String
SharedString(&'a str),
/// Boolean
Bool(bool),
/// Date or Time
DateTime(f64),
/// Duration
Duration(f64),
/// Date, Time or DateTime in ISO 8601
DateTimeIso(String),
/// Duration in ISO 8601
DurationIso(String),
/// Error
Error(CellErrorType),
/// Empty cell
#[default]
Empty,
}

impl<'a> From<DataTypeRef<'a>> for DataType {
fn from(value: DataTypeRef<'a>) -> Self {
match value {
DataTypeRef::Int(v) => DataType::Int(v),
DataTypeRef::Float(v) => DataType::Float(v),
DataTypeRef::String(v) => DataType::String(v),
DataTypeRef::SharedString(v) => DataType::String(v.into()),
DataTypeRef::Bool(v) => DataType::Bool(v),
DataTypeRef::DateTime(v) => DataType::DateTime(v),
DataTypeRef::Duration(v) => DataType::Duration(v),
DataTypeRef::DateTimeIso(v) => DataType::DateTimeIso(v),
DataTypeRef::DurationIso(v) => DataType::DurationIso(v),
DataTypeRef::Error(v) => DataType::Error(v),
DataTypeRef::Empty => DataType::Empty,
}
}
}

#[cfg(all(test, feature = "dates"))]
mod date_tests {
use super::*;
Expand Down
20 changes: 15 additions & 5 deletions src/formats.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::DataType;
use crate::{datatype::DataTypeRef, DataType};

/// https://learn.microsoft.com/en-us/office/troubleshoot/excel/1900-and-1904-date-system
static EXCEL_1900_1904_DIFF: i64 = 1462;
Expand Down Expand Up @@ -104,18 +104,28 @@ pub fn format_excel_i64(value: i64, format: Option<&CellFormat>, is_1904: bool)
}

// convert f64 to date, if format == Date
pub fn format_excel_f64(value: f64, format: Option<&CellFormat>, is_1904: bool) -> DataType {
#[inline]
pub fn format_excel_f64_ref<'a>(
value: f64,
format: Option<&CellFormat>,
is_1904: bool,
) -> DataTypeRef<'static> {
match format {
Some(CellFormat::DateTime) => DataType::DateTime(if is_1904 {
Some(CellFormat::DateTime) => DataTypeRef::DateTime(if is_1904 {
value + EXCEL_1900_1904_DIFF as f64
} else {
value
}),
Some(CellFormat::TimeDelta) => DataType::Duration(value),
_ => DataType::Float(value),
Some(CellFormat::TimeDelta) => DataTypeRef::Duration(value),
_ => DataTypeRef::Float(value),
}
}

// convert f64 to date, if format == Date
pub fn format_excel_f64(value: f64, format: Option<&CellFormat>, is_1904: bool) -> DataType {
format_excel_f64_ref(value, format, is_1904).into()
}

/// Ported from openpyxl, MIT License
/// https://foss.heptapod.net/openpyxl/openpyxl/-/blob/a5e197c530aaa49814fd1d993dd776edcec35105/openpyxl/styles/tests/test_number_style.py
#[test]
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ mod de;
mod errors;
pub mod vba;

use datatype::DataTypeRef;
use serde::de::DeserializeOwned;
use std::borrow::Cow;
use std::cmp::{max, min};
Expand Down Expand Up @@ -279,6 +280,7 @@ where
pub trait CellType: Default + Clone + PartialEq {}

impl CellType for DataType {}
impl<'a> CellType for DataTypeRef<'a> {}
impl CellType for String {}
impl CellType for usize {} // for tests

Expand Down
Loading

0 comments on commit 1271ef1

Please sign in to comment.