excel_cli/json_export/
converters.rs1use chrono::{Duration, NaiveDate, NaiveDateTime};
2use serde_json::{json, Value};
3
4use crate::excel::{Cell, CellType, DataTypeInfo};
5
6pub fn excel_date_to_iso_string(excel_date: f64) -> String {
8 let days = if excel_date > 59.0 {
9 excel_date - 1.0
10 } else {
11 excel_date
12 };
13
14 let base_date = NaiveDate::from_ymd_opt(1900, 1, 1).unwrap();
15 let whole_days = days.trunc() as i64;
16 let fractional_day = days.fract();
17
18 let date = base_date + Duration::days(whole_days - 1); if fractional_day > 0.0 {
21 let seconds_in_day = 24.0 * 60.0 * 60.0;
22 let seconds = (fractional_day * seconds_in_day).round() as u32;
23
24 let hours = seconds / 3600;
25 let minutes = (seconds % 3600) / 60;
26 let secs = seconds % 60;
27
28 let datetime = NaiveDateTime::new(
29 date,
30 chrono::NaiveTime::from_hms_opt(hours, minutes, secs).unwrap(),
31 );
32
33 datetime.format("%Y-%m-%dT%H:%M:%S").to_string()
34 } else {
35 date.format("%Y-%m-%d").to_string()
36 }
37}
38
39pub fn process_cell_value(cell: &Cell) -> Value {
41 if cell.value.is_empty() {
42 return Value::Null;
43 }
44
45 if let Some(original_type) = &cell.original_type {
46 match original_type {
47 DataTypeInfo::Float(f) => {
48 if f.fract() == 0.0 {
49 json!(f.trunc() as i64)
50 } else {
51 json!(f)
52 }
53 }
54 DataTypeInfo::Int(i) => json!(i),
55 DataTypeInfo::DateTime(dt) => {
56 if *dt >= 0.0 {
57 json!(excel_date_to_iso_string(*dt))
58 } else {
59 json!(cell.value)
60 }
61 }
62 DataTypeInfo::DateTimeIso(s) => json!(s),
63 DataTypeInfo::Bool(b) => json!(b),
64 DataTypeInfo::Empty => Value::Null,
65 _ => json!(cell.value),
66 }
67 } else {
68 match cell.cell_type {
69 CellType::Number => {
70 if let Ok(num) = cell.value.parse::<f64>() {
71 if num.fract() == 0.0 {
72 json!(num.trunc() as i64)
73 } else {
74 json!(num)
75 }
76 } else {
77 json!(cell.value)
78 }
79 }
80 CellType::Boolean => {
81 if cell.value.to_lowercase() == "true" {
82 json!(true)
83 } else if cell.value.to_lowercase() == "false" {
84 json!(false)
85 } else {
86 json!(cell.value)
87 }
88 }
89 CellType::Date => {
90 if let Ok(excel_date) = cell.value.parse::<f64>() {
91 if excel_date >= 0.0 {
92 json!(excel_date_to_iso_string(excel_date))
93 } else {
94 json!(cell.value)
95 }
96 } else {
97 json!(cell.value)
98 }
99 }
100 CellType::Empty => Value::Null,
101 _ => json!(cell.value), }
103 }
104}