1use crate::errors::Result;
7use crate::file::File;
8use crate::xml::workbook::{CalcPropsOptions, WorkbookPropsOptions, WorkbookProtectionOptions};
9use crate::xml::worksheet::XlsxWorksheet;
10
11pub fn check_sheet_name(name: &str) -> Result<()> {
13 <File as ExcelizeCore>::check_sheet_name(name)
14}
15
16pub trait ExcelizeCore {
18 fn check_sheet_name(name: &str) -> Result<()>;
20
21 fn check_open_reader_options(&self) -> Result<()>;
23
24 fn work_sheet_reader(&self, sheet: &str) -> Result<XlsxWorksheet>;
26
27 fn update_linked_value(&self) -> Result<()>;
29
30 fn add_vba_project(&self, data: &[u8]) -> Result<()>;
32
33 fn set_content_type_part_project_extensions(&self, content_type: &str) -> Result<()>;
35
36 fn set_workbook_props(&self, opts: &WorkbookPropsOptions) -> Result<()>;
38
39 fn get_workbook_props(&self) -> Result<WorkbookPropsOptions>;
41
42 fn set_calc_props(&self, opts: &CalcPropsOptions) -> Result<()>;
44
45 fn get_calc_props(&self) -> Result<CalcPropsOptions>;
47
48 fn protect_workbook(&self, opts: &WorkbookProtectionOptions) -> Result<()>;
50
51 fn unprotect_workbook(&self, password: Option<&str>) -> Result<()>;
53}
54
55impl ExcelizeCore for File {
56 fn check_sheet_name(name: &str) -> Result<()> {
57 if name.is_empty() {
58 return Err(Box::new(crate::errors::ErrSheetNameBlank));
59 }
60 if crate::lib_util::count_utf16_string(name) > crate::constants::MAX_SHEET_NAME_LENGTH {
61 return Err(Box::new(crate::errors::ErrSheetNameLength));
62 }
63 if name.starts_with('\'') || name.ends_with('\'') {
64 return Err(Box::new(crate::errors::ErrSheetNameSingleQuote));
65 }
66 if name.contains(|c: char| matches!(c, ':'))
67 || name.contains('\\')
68 || name.contains('/')
69 || name.contains('?')
70 || name.contains('*')
71 || name.contains('[')
72 || name.contains(']')
73 {
74 return Err(Box::new(crate::errors::ErrSheetNameInvalid));
75 }
76 Ok(())
77 }
78
79 fn check_open_reader_options(&self) -> Result<()> {
80 self.check_open_reader_options()
81 }
82
83 fn work_sheet_reader(&self, sheet: &str) -> Result<XlsxWorksheet> {
84 File::work_sheet_reader(self, sheet)
85 }
86
87 fn update_linked_value(&self) -> Result<()> {
88 let mut wb = self.workbook_reader()?;
89 wb.calc_pr = None;
91 *self.workbook.lock().unwrap() = Some(wb);
92 for name in self.get_sheet_list() {
93 let mut ws = self.work_sheet_reader(&name)?;
94 for row in &mut ws.sheet_data.row {
95 for cell in &mut row.c {
96 if cell.f.is_some() && cell.v.is_some() {
97 cell.v = None;
98 cell.t = None;
99 }
100 }
101 }
102 if let Some(path) = self.get_sheet_xml_path(&name) {
103 self.sheet.insert(path, ws);
104 }
105 }
106 Ok(())
107 }
108
109 fn add_vba_project(&self, data: &[u8]) -> Result<()> {
110 crate::file::add_vba_project(self, data)
111 }
112
113 fn set_content_type_part_project_extensions(&self, content_type: &str) -> Result<()> {
114 crate::file::set_content_type_part_project_extensions(self, content_type)
115 }
116
117 fn set_workbook_props(&self, opts: &WorkbookPropsOptions) -> Result<()> {
118 File::set_workbook_props(self, opts)
119 }
120
121 fn get_workbook_props(&self) -> Result<WorkbookPropsOptions> {
122 File::get_workbook_props(self)
123 }
124
125 fn set_calc_props(&self, opts: &CalcPropsOptions) -> Result<()> {
126 File::set_calc_props(self, opts)
127 }
128
129 fn get_calc_props(&self) -> Result<CalcPropsOptions> {
130 File::get_calc_props(self)
131 }
132
133 fn protect_workbook(&self, opts: &WorkbookProtectionOptions) -> Result<()> {
134 File::protect_workbook(self, opts)
135 }
136
137 fn unprotect_workbook(&self, password: Option<&str>) -> Result<()> {
138 File::unprotect_workbook(self, password)
139 }
140}