Skip to main content

miniexcel/
options.rs

1use indexmap::IndexMap;
2
3use crate::CellReference;
4
5#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
6pub enum HeaderMode {
7    #[default]
8    Auto,
9    None,
10    FirstRow,
11}
12
13#[derive(Clone, Debug, Eq, PartialEq)]
14pub struct ReadOptions {
15    sheet_name: Option<String>,
16    start_cell: CellReference,
17    end_cell: Option<CellReference>,
18    header_mode: HeaderMode,
19    ignore_empty_rows: bool,
20    trim_headers: bool,
21}
22
23impl ReadOptions {
24    #[must_use]
25    pub fn new() -> Self {
26        Self::default()
27    }
28
29    #[must_use]
30    pub fn with_sheet_name(mut self, sheet_name: impl Into<String>) -> Self {
31        self.sheet_name = Some(sheet_name.into());
32        self
33    }
34
35    #[must_use]
36    pub const fn with_start_cell(mut self, start_cell: CellReference) -> Self {
37        self.start_cell = start_cell;
38        self
39    }
40
41    #[must_use]
42    pub const fn with_end_cell(mut self, end_cell: CellReference) -> Self {
43        self.end_cell = Some(end_cell);
44        self
45    }
46
47    #[must_use]
48    pub const fn with_header_mode(mut self, header_mode: HeaderMode) -> Self {
49        self.header_mode = header_mode;
50        self
51    }
52
53    #[must_use]
54    pub const fn with_ignore_empty_rows(mut self, ignore_empty_rows: bool) -> Self {
55        self.ignore_empty_rows = ignore_empty_rows;
56        self
57    }
58
59    #[must_use]
60    pub const fn with_trim_headers(mut self, trim_headers: bool) -> Self {
61        self.trim_headers = trim_headers;
62        self
63    }
64
65    #[must_use]
66    pub(crate) fn sheet_name(&self) -> Option<&str> {
67        self.sheet_name.as_deref()
68    }
69
70    #[must_use]
71    pub(crate) const fn start_cell(&self) -> CellReference {
72        self.start_cell
73    }
74
75    #[must_use]
76    pub(crate) const fn end_cell(&self) -> Option<CellReference> {
77        self.end_cell
78    }
79
80    #[must_use]
81    pub(crate) const fn ignore_empty_rows(&self) -> bool {
82        self.ignore_empty_rows
83    }
84
85    #[must_use]
86    pub(crate) const fn trim_headers(&self) -> bool {
87        self.trim_headers
88    }
89
90    pub(crate) const fn uses_headers(&self, typed: bool) -> bool {
91        match self.header_mode {
92            HeaderMode::Auto => typed,
93            HeaderMode::None => false,
94            HeaderMode::FirstRow => true,
95        }
96    }
97}
98
99impl Default for ReadOptions {
100    fn default() -> Self {
101        Self {
102            sheet_name: None,
103            start_cell: CellReference::A1,
104            end_cell: None,
105            header_mode: HeaderMode::Auto,
106            ignore_empty_rows: false,
107            trim_headers: true,
108        }
109    }
110}
111
112#[derive(Clone, Debug, Eq, PartialEq)]
113pub struct WriteOptions {
114    sheet_name: String,
115    print_header: bool,
116    date_format: String,
117    time_format: String,
118    datetime_format: String,
119    duration_format: String,
120    column_formats: IndexMap<String, String>,
121}
122
123impl WriteOptions {
124    #[must_use]
125    pub fn new() -> Self {
126        Self::default()
127    }
128
129    #[must_use]
130    pub fn with_sheet_name(mut self, sheet_name: impl Into<String>) -> Self {
131        self.sheet_name = sheet_name.into();
132        self
133    }
134
135    #[must_use]
136    pub const fn with_print_header(mut self, print_header: bool) -> Self {
137        self.print_header = print_header;
138        self
139    }
140
141    #[must_use]
142    pub fn with_date_format(mut self, format: impl Into<String>) -> Self {
143        self.date_format = format.into();
144        self
145    }
146
147    #[must_use]
148    pub fn with_time_format(mut self, format: impl Into<String>) -> Self {
149        self.time_format = format.into();
150        self
151    }
152
153    #[must_use]
154    pub fn with_datetime_format(mut self, format: impl Into<String>) -> Self {
155        self.datetime_format = format.into();
156        self
157    }
158
159    #[must_use]
160    pub fn with_duration_format(mut self, format: impl Into<String>) -> Self {
161        self.duration_format = format.into();
162        self
163    }
164
165    #[must_use]
166    pub fn with_column_format(
167        mut self,
168        field_name: impl Into<String>,
169        format: impl Into<String>,
170    ) -> Self {
171        self.column_formats.insert(field_name.into(), format.into());
172        self
173    }
174
175    #[must_use]
176    pub(crate) fn sheet_name(&self) -> &str {
177        &self.sheet_name
178    }
179
180    #[must_use]
181    pub(crate) const fn print_header(&self) -> bool {
182        self.print_header
183    }
184
185    #[must_use]
186    pub(crate) fn date_format(&self) -> &str {
187        &self.date_format
188    }
189
190    #[must_use]
191    pub(crate) fn time_format(&self) -> &str {
192        &self.time_format
193    }
194
195    #[must_use]
196    pub(crate) fn datetime_format(&self) -> &str {
197        &self.datetime_format
198    }
199
200    #[must_use]
201    pub(crate) fn duration_format(&self) -> &str {
202        &self.duration_format
203    }
204
205    #[must_use]
206    pub(crate) fn column_formats(&self) -> &IndexMap<String, String> {
207        &self.column_formats
208    }
209}
210
211impl Default for WriteOptions {
212    fn default() -> Self {
213        Self {
214            sheet_name: "Sheet1".to_owned(),
215            print_header: true,
216            date_format: "yyyy-mm-dd".to_owned(),
217            time_format: "hh:mm:ss".to_owned(),
218            datetime_format: "yyyy-mm-dd hh:mm:ss".to_owned(),
219            duration_format: "[h]:mm:ss".to_owned(),
220            column_formats: IndexMap::new(),
221        }
222    }
223}