edit_xlsx/xml/worksheet/
sheet_data.rs

1//! Some traits for managing deserialized Rows
2//! - Add, modify and delete Rows.
3//! - Add, modify and delete Cells in a Row by calling the Cells trait.
4pub(crate) mod cell;
5mod row;
6
7use serde::{Deserialize, Serialize};
8use crate::api::cell::location::Location;
9use crate::api::cell::Cell as ApiCell;
10use crate::api::cell::values::{CellDisplay, CellType, CellValue};
11use crate::api::worksheet::row::Row as ApiRow;
12use crate::result::CellError::CellNotFound;
13use crate::result::RowError::RowNotFound;
14use crate::result::{RowError, RowResult};
15use crate::xml::worksheet::sheet_data::cell::Cell;
16use crate::xml::worksheet::sheet_data::row::{_OrderCell, Row};
17
18#[derive(Debug, Clone, Serialize, Deserialize, Default)]
19pub(crate) struct SheetData {
20    // Rows are ordered
21    #[serde(rename = "row", default)]
22    rows: Vec<Row>,
23}
24
25impl SheetData {
26    pub(crate) fn max_col(&self) -> u32 {
27        match self.rows.iter().max_by_key(|row| { row.max_col() }) {
28            Some(row) => row.max_col(),
29            None => 0
30        }
31    }
32
33    pub(crate) fn max_row(&self) -> u32 {
34        match self.rows.last() {
35            Some(row) => row.row,
36            None => 0
37        }
38    }
39
40    // pub(crate) fn get_row_height(&self, row: u32) -> WorkSheetResult<f64> {
41    //     match self.get_row(row) {
42    //         Some(row) => row.height.ok_or(RowError(CellError(CellNotFound))),
43    //         None => Err(RowError(RowNotFound))
44    //     }
45    // }
46
47    pub(crate) fn get_api_row(&self, row: u32) -> RowResult<ApiRow> {
48        match self.get_row(row) {
49            Some(row) => Ok(row.to_api_row()),
50            None => Err(RowNotFound)
51        }
52    }
53
54    pub(crate) fn set_by_row(&mut self, row: u32, row_set: &ApiRow) {
55        let row = self.get_or_new_row(row);
56        if let Some(height) = row_set.height {
57            row.height = Some(height);
58            row.custom_height = Some(1);
59        }
60        if let Some(style) = row_set.style {
61            row.style = Some(style);
62            row.custom_format = Some(1);
63        }
64        if let Some(hidden) = row_set.hidden {
65            row.hidden = Some(hidden)
66        }
67        if let Some(outline_level) = row_set.outline_level {
68            row.outline_level = Some(outline_level)
69        }
70        if let Some(collapsed) = row_set.collapsed {
71            row.collapsed = Some(collapsed)
72        }
73    }
74
75    pub(crate) fn get_cell_type<L: Location>(&self, loc: &L) -> Option<&CellType> {
76        let row = self.get_row(loc.to_row());
77        match row {
78            Some(row) => {
79                let col = loc.to_col();
80                let cell = row.get_cell(col);
81                match cell {
82                    Some(cell) => cell.cell_type.as_ref(),
83                    None => None,
84                }
85            },
86            None => None,
87        }
88    }
89
90    pub(crate) fn get_value<L: Location>(&self, loc: &L) -> Option<&str> {
91        let (row, col) = loc.to_location();
92        let row = self.get_row(row);
93        match row {
94            Some(row) => {
95                row.get_display_cell(col).map(|v|v.as_ref())
96            },
97            None => None
98        }
99    }
100
101    pub(crate) fn get_default_style<L: Location>(&self, loc: &L) -> Option<u32> {
102        let row = self.get_row(loc.to_row());
103        match row {
104            Some(row) => {
105                let col = loc.to_col();
106                // let cell = row.cells.iter().find(|cell| cell.loc.col == col);
107                let cell = row.get_cell(col);
108                match cell {
109                    Some(cell) => cell.style,
110                    None => row.style,
111                }
112            },
113            None => None,
114        }
115    }
116
117    pub(crate) fn write_by_api_cell<L: Location, T: CellDisplay + CellValue>(&mut self, loc: &L, api_cell: &ApiCell<T>) -> RowResult<()> {
118        let (row, col) = loc.to_location();
119        let row = self.get_or_new_row(row);
120        row.add_by_api_cell(col, &api_cell)?;
121        Ok(())
122    }
123
124    pub(crate) fn read_api_cell<L: Location>(&self, loc: &L) -> RowResult<ApiCell<String>> {
125        let (row, col) = loc.to_location();
126        if let Some(row) = self.get_row(row) {
127            match row.get_cell(col) {
128                Some(cell) => Ok(cell.to_api_cell()),
129                None => Err(RowError::CellError(CellNotFound)),
130            }
131        } else {
132            Err(RowError::RowNotFound)
133        }
134    }
135
136    pub(crate) fn write_display<L: Location, T: CellDisplay + CellValue>(&mut self, loc: &L, text: &T, style: Option<u32>) -> RowResult<()> {
137        let (row, col) = loc.to_location();
138        let row = self.get_or_new_row(row);
139        row.add_display_cell(col, text, style);
140        // row.add_cell(col, Some(text), None, None, style);
141        Ok(())
142    }
143
144    // pub(crate) fn write_formula<L: Location>(&mut self, loc: &L, formula: &str, formula_type: FormulaType, style: Option<u32>) -> RowResult<()> {
145    //     let (row, col) = loc.to_location();
146    //     let row = self.get_or_new_row(row);
147    //     row.add_formula_cell(col, formula, formula_type, style);
148    //     Ok(())
149    // }
150
151    pub(crate) fn clean_formula_value(&mut self) {
152        // self.rows.iter_mut().for_each(
153        //     |row| row.cells.iter_mut().for_each(|cell|
154        //         if let Some(_) = cell.formula {
155        //             cell.text = None;
156        //         }
157        //     )
158        // )
159    }
160}
161
162trait _OrderRow {
163    fn get_position_by_row(&self, row: u32) -> usize;
164    fn new_row(&mut self, row: u32) -> &mut Row;
165    fn get_row_mut(&mut self, row: u32) -> Option<&mut Row>;
166    fn get_row(&self, row: u32) -> Option<&Row>;
167    fn get_or_new_row(&mut self, row: u32) -> &mut Row;
168    fn get_last_row(&self) -> Option<&Row>;
169}
170
171impl _OrderRow for SheetData {
172    fn get_position_by_row(&self, row: u32) -> usize {
173        let mut l = 0;
174        let mut r = self.rows.len();
175        while r - l > 0 {
176            let mid = (l + r) / 2;
177            if row == self.rows[mid].row {
178                return mid;
179            }
180            else if row < self.rows[mid].row {
181                r = mid;
182            } else {
183                l = mid + 1;
184            }
185        }
186        r
187    }
188    fn new_row(&mut self, row: u32) -> &mut Row {
189        let r = self.get_position_by_row(row);
190        self.rows.insert(r, Row::new(row));
191        return &mut self.rows[r];
192    }
193    fn get_row_mut(&mut self, row: u32) -> Option<&mut Row> {
194        let r = self.get_position_by_row(row);
195        if r >= self.rows.len() {return None}
196        return if row == self.rows[r].row { Some(&mut self.rows[r]) } else { None }
197    }
198    fn get_row(&self, row: u32) -> Option<&Row> {
199        let r = self.get_position_by_row(row);
200        if r >= self.rows.len() {return None}
201        return if row == self.rows[r].row { Some(&self.rows[r]) } else { None }
202    }
203    fn get_or_new_row(&mut self, row: u32) -> &mut Row {
204        let r = self.get_position_by_row(row);
205        return if r < self.rows.len() && self.rows[r].row == row {
206            &mut self.rows[r]
207        } else {
208            self.rows.insert(r, Row::new(row));
209            &mut self.rows[r]
210        }
211    }
212    fn get_last_row(&self) -> Option<&Row> {
213        self.rows.last()
214    }
215}