Skip to content

Commit 9e68136

Browse files
improved CString error handling
1 parent 4348101 commit 9e68136

File tree

9 files changed

+230
-144
lines changed

9 files changed

+230
-144
lines changed

libxlsxwriter/src/chart/mod.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ mod constants;
22
mod series;
33
mod structs;
44

5+
use crate::XlsxError;
6+
57
pub use self::constants::*;
68
pub use self::series::*;
79
pub use self::structs::*;
@@ -17,9 +19,9 @@ use super::Workbook;
1719
/// let mut worksheet = workbook.add_worksheet(None)?;
1820
/// write_worksheet(&mut worksheet)?; // write worksheet contents
1921
/// let mut chart = workbook.add_chart(ChartType::Column);
20-
/// chart.add_series(None, Some("=Sheet1!$A$1:$A$5"));
21-
/// chart.add_series(None, Some("=Sheet1!$B$1:$B$5"));
22-
/// chart.add_series(None, Some("=Sheet1!$C$1:$C$5"));
22+
/// chart.add_series(None, Some("=Sheet1!$A$1:$A$5"))?;
23+
/// chart.add_series(None, Some("=Sheet1!$B$1:$B$5"))?;
24+
/// chart.add_series(None, Some("=Sheet1!$C$1:$C$5"))?;
2325
/// worksheet.insert_chart(1, 3, &chart)?;
2426
/// workbook.close()
2527
/// # }
@@ -58,7 +60,7 @@ impl<'a> Chart<'a> {
5860
/// # let mut worksheet = workbook.add_worksheet(None)?;
5961
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
6062
/// # let mut chart = workbook.add_chart(ChartType::Column);
61-
/// chart.add_series(Some("=Sheet1!$A$1:$A$5"), Some("=Sheet1!$B$1:$B$5"));
63+
/// chart.add_series(Some("=Sheet1!$A$1:$A$5"), Some("=Sheet1!$B$1:$B$5"))?;
6264
/// # worksheet.insert_chart(1, 3, &chart)?;
6365
/// # workbook.close()
6466
/// # }
@@ -80,7 +82,7 @@ impl<'a> Chart<'a> {
8082
/// # let mut worksheet = workbook.add_worksheet(None)?;
8183
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
8284
/// # let mut chart = workbook.add_chart(ChartType::Column);
83-
/// chart.add_series(None, Some("=Sheet1!$B$1:$B$5"));
85+
/// chart.add_series(None, Some("=Sheet1!$B$1:$B$5"))?;
8486
/// # worksheet.insert_chart(1, 3, &chart)?;
8587
/// # workbook.close()
8688
/// # }
@@ -102,7 +104,7 @@ impl<'a> Chart<'a> {
102104
/// # let mut worksheet = workbook.add_worksheet(None)?;
103105
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
104106
/// # let mut chart = workbook.add_chart(ChartType::Column);
105-
/// let mut series = chart.add_series(None, None);
107+
/// let mut series = chart.add_series(None, None)?;
106108
/// series.set_categories("Sheet1", 0, 0, 4, 0); // "=Sheet1!$A$1:$A$5"
107109
/// series.set_values("Sheet1", 0, 1, 4, 1); // "=Sheet1!$B$1:$B$5"
108110
/// # worksheet.insert_chart(1, 3, &chart)?;
@@ -150,7 +152,7 @@ impl<'a> Chart<'a> {
150152
/// # let mut worksheet = workbook.add_worksheet(None)?;
151153
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
152154
/// # let mut chart = workbook.add_chart(ChartType::Column);
153-
/// chart.add_series(Some("=(Sheet1!$A$1:$A$5,Sheet1!$A$10:$A$18)"), Some("=(Sheet1!$B$1:$B$5,Sheet1!$B$10:$B$18)"));
155+
/// chart.add_series(Some("=(Sheet1!$A$1:$A$5,Sheet1!$A$10:$A$18)"), Some("=(Sheet1!$B$1:$B$5,Sheet1!$B$10:$B$18)"))?;
154156
/// # worksheet.insert_chart(1, 3, &chart)?;
155157
/// # workbook.close()
156158
/// # }
@@ -167,26 +169,27 @@ impl<'a> Chart<'a> {
167169
&mut self,
168170
categories: Option<&str>,
169171
values: Option<&str>,
170-
) -> ChartSeries<'a> {
172+
) -> Result<ChartSeries<'a>, XlsxError> {
171173
let series = unsafe {
172174
libxlsxwriter_sys::chart_add_series(
173175
self.chart,
174-
self._workbook.register_option_str(categories),
175-
self._workbook.register_option_str(values),
176+
self._workbook.register_option_str(categories)?,
177+
self._workbook.register_option_str(values)?,
176178
)
177179
};
178-
ChartSeries {
180+
Ok(ChartSeries {
179181
_workbook: self._workbook,
180182
chart_series: series,
181-
}
183+
})
182184
}
183185

184186
/// The chart_title_set_name() function sets the name (title) for the chart. The name is displayed above the chart.
185187
/// The name parameter can also be a formula such as `=Sheet1!$A$1` to point to a cell in the workbook that contains the name.
186188
/// The Excel default is to have no chart title.
187-
pub fn add_title(&mut self, title: &str) {
189+
pub fn add_title(&mut self, title: &str) -> Result<(), XlsxError> {
188190
unsafe {
189-
libxlsxwriter_sys::chart_title_set_name(self.chart, self._workbook.register_str(title))
191+
libxlsxwriter_sys::chart_title_set_name(self.chart, self._workbook.register_str(title)?)
190192
}
193+
Ok(())
191194
}
192195
}

libxlsxwriter/src/chart/series.rs

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::constants::*;
22
use super::structs::*;
3+
use crate::XlsxError;
34
use crate::{convert_bool, Workbook, WorksheetCol, WorksheetRow};
45

56
/// Struct to represent an Excel chart data series.
@@ -20,7 +21,7 @@ impl<'a> ChartSeries<'a> {
2021
/// # let mut worksheet = workbook.add_worksheet(None)?;
2122
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
2223
/// # let mut chart = workbook.add_chart(ChartType::Column);
23-
/// let mut series = chart.add_series(None, None);
24+
/// let mut series = chart.add_series(None, None)?;
2425
/// series.set_categories("Sheet1", 0, 0, 4, 0); // "=Sheet1!$A$1:$A$5"
2526
/// series.set_values("Sheet1", 0, 1, 4, 1); // "=Sheet1!$B$1:$B$5"
2627
/// # worksheet.insert_chart(1, 3, &chart)?;
@@ -41,17 +42,18 @@ impl<'a> ChartSeries<'a> {
4142
first_column: WorksheetCol,
4243
last_row: WorksheetRow,
4344
last_column: WorksheetCol,
44-
) {
45+
) -> Result<(), XlsxError> {
4546
unsafe {
4647
libxlsxwriter_sys::chart_series_set_categories(
4748
self.chart_series,
48-
self._workbook.register_str(sheet_name),
49+
self._workbook.register_str(sheet_name)?,
4950
first_row,
5051
first_column,
5152
last_row,
5253
last_column,
5354
);
5455
}
56+
Ok(())
5557
}
5658

5759
/// The categories and values of a chart data series are generally set using the `Chart.add_series()` function and Excel range formulas like "=Sheet1!$A$2:$A$7".
@@ -64,17 +66,18 @@ impl<'a> ChartSeries<'a> {
6466
first_column: WorksheetCol,
6567
last_row: WorksheetRow,
6668
last_column: WorksheetCol,
67-
) {
69+
) -> Result<(), XlsxError> {
6870
unsafe {
6971
libxlsxwriter_sys::chart_series_set_values(
7072
self.chart_series,
71-
self._workbook.register_str(sheet_name),
73+
self._workbook.register_str(sheet_name)?,
7274
first_row,
7375
first_column,
7476
last_row,
7577
last_column,
7678
);
7779
}
80+
Ok(())
7881
}
7982

8083
/// This function is used to set the name for a chart data series. The series name in Excel is displayed in the chart legend and in the formula bar. The name property is optional and if it isn't supplied it will default to `Series 1..n`.
@@ -86,7 +89,7 @@ impl<'a> ChartSeries<'a> {
8689
/// # let mut worksheet = workbook.add_worksheet(None)?;
8790
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
8891
/// # let mut chart = workbook.add_chart(ChartType::Column);
89-
/// let mut series = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
92+
/// let mut series = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
9093
/// series.set_name("Quarterly budget data");
9194
/// # worksheet.insert_chart(1, 3, &chart)?;
9295
/// # workbook.close()
@@ -112,7 +115,7 @@ impl<'a> ChartSeries<'a> {
112115
/// # let mut worksheet = workbook.add_worksheet(None)?;
113116
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
114117
/// # let mut chart = workbook.add_chart(ChartType::Column);
115-
/// let mut series = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
118+
/// let mut series = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
116119
/// series.set_name("=Sheet1!$A$1:$A$1");
117120
/// # worksheet.insert_chart(1, 3, &chart)?;
118121
/// # workbook.close()
@@ -129,13 +132,14 @@ impl<'a> ChartSeries<'a> {
129132
/// # Ok(())
130133
/// # }
131134
/// ```
132-
pub fn set_name(&mut self, name: &str) {
135+
pub fn set_name(&mut self, name: &str) -> Result<(), XlsxError> {
133136
unsafe {
134137
libxlsxwriter_sys::chart_series_set_name(
135138
self.chart_series,
136-
self._workbook.register_str(name),
139+
self._workbook.register_str(name)?,
137140
);
138141
}
142+
Ok(())
139143
}
140144

141145
/// The `ChartSeries.set_name_range()` function can be used to set a series name range and is an alternative to using `ChartSeries.set_name()` and a string formula:
@@ -146,7 +150,7 @@ impl<'a> ChartSeries<'a> {
146150
/// # let mut worksheet = workbook.add_worksheet(None)?;
147151
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
148152
/// # let mut chart = workbook.add_chart(ChartType::Column);
149-
/// let mut series = chart.add_series(None, Some("=Sheet1!$B$2:$B$6"));
153+
/// let mut series = chart.add_series(None, Some("=Sheet1!$B$2:$B$6"))?;
150154
/// series.set_name_range("Sheet1", 0, 1); // =Sheet1!$B$1
151155
/// # worksheet.insert_chart(1, 3, &chart)?;
152156
/// # workbook.close()
@@ -163,15 +167,21 @@ impl<'a> ChartSeries<'a> {
163167
/// # Ok(())
164168
/// # }
165169
/// ```
166-
pub fn set_name_range(&mut self, sheet_name: &str, row: WorksheetRow, column: WorksheetCol) {
170+
pub fn set_name_range(
171+
&mut self,
172+
sheet_name: &str,
173+
row: WorksheetRow,
174+
column: WorksheetCol,
175+
) -> Result<(), XlsxError> {
167176
unsafe {
168177
libxlsxwriter_sys::chart_series_set_name_range(
169178
self.chart_series,
170-
self._workbook.register_str(sheet_name),
179+
self._workbook.register_str(sheet_name)?,
171180
row,
172181
column,
173182
);
174183
}
184+
Ok(())
175185
}
176186

177187
/// Set the line/border properties of a chart series:
@@ -182,9 +192,9 @@ impl<'a> ChartSeries<'a> {
182192
/// # let mut worksheet = workbook.add_worksheet(None)?;
183193
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
184194
/// # let mut chart = workbook.add_chart(ChartType::Column);
185-
/// let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
186-
/// let mut series2 = chart.add_series(None, Some("=Sheet1!$B$2:$B$6"));
187-
/// let mut series3 = chart.add_series(None, Some("=Sheet1!$C$2:$C$6"));
195+
/// let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
196+
/// let mut series2 = chart.add_series(None, Some("=Sheet1!$B$2:$B$6"))?;
197+
/// let mut series3 = chart.add_series(None, Some("=Sheet1!$C$2:$C$6"))?;
188198
/// let mut chart_line = ChartLine::new();
189199
/// chart_line.color = FormatColor::Red;
190200
/// series1.set_line(&chart_line);
@@ -220,9 +230,9 @@ impl<'a> ChartSeries<'a> {
220230
/// # let mut worksheet = workbook.add_worksheet(None)?;
221231
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
222232
/// # let mut chart = workbook.add_chart(ChartType::Column);
223-
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
224-
/// # let mut series2 = chart.add_series(None, Some("=Sheet1!$B$2:$B$6"));
225-
/// # let mut series3 = chart.add_series(None, Some("=Sheet1!$C$2:$C$6"));
233+
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
234+
/// # let mut series2 = chart.add_series(None, Some("=Sheet1!$B$2:$B$6"))?;
235+
/// # let mut series3 = chart.add_series(None, Some("=Sheet1!$C$2:$C$6"))?;
226236
/// let mut chart_fill_1 = ChartFill::new();
227237
/// chart_fill_1.color = FormatColor::Red;
228238
/// let mut chart_fill_2 = ChartFill::new();
@@ -262,9 +272,9 @@ impl<'a> ChartSeries<'a> {
262272
/// # let mut worksheet = workbook.add_worksheet(None)?;
263273
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
264274
/// # let mut chart = workbook.add_chart(ChartType::Column);
265-
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
266-
/// # let mut series2 = chart.add_series(None, Some("=Sheet1!$B$2:$B$6"));
267-
/// # let mut series3 = chart.add_series(None, Some("=Sheet1!$C$2:$C$6"));
275+
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
276+
/// # let mut series2 = chart.add_series(None, Some("=Sheet1!$B$2:$B$6"))?;
277+
/// # let mut series3 = chart.add_series(None, Some("=Sheet1!$C$2:$C$6"))?;
268278
/// # series1.set_name("=Sheet1!$A$1");
269279
/// # series2.set_name("=Sheet1!$B$1");
270280
/// # series3.set_name("=Sheet1!$C$1");
@@ -310,8 +320,8 @@ impl<'a> ChartSeries<'a> {
310320
/// # let mut worksheet = workbook.add_worksheet(None)?;
311321
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
312322
/// # let mut chart = workbook.add_chart(ChartType::Column);
313-
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
314-
/// # let mut series2 = chart.add_series(None, Some("=Sheet1!$B$2:$B$6"));
323+
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
324+
/// # let mut series2 = chart.add_series(None, Some("=Sheet1!$B$2:$B$6"))?;
315325
/// # series1.set_name("=Sheet1!$A$1");
316326
/// # series2.set_name("=Sheet1!$B$1");
317327
/// let pattern1 = ChartPattern::new(FormatColor::Custom(0x804000), FormatColor::Custom(0xC68C53), ChartPatternType::Shingle);
@@ -347,7 +357,7 @@ impl<'a> ChartSeries<'a> {
347357
/// # let mut worksheet = workbook.add_worksheet(None)?;
348358
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
349359
/// # let mut chart = workbook.add_chart(ChartType::Line);
350-
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
360+
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
351361
/// # series1.set_name("=Sheet1!$A$1");
352362
/// series1.set_marker_type(ChartMarkerType::MarkerDiamond);
353363
/// # worksheet.insert_chart(1, 3, &chart)?;
@@ -377,7 +387,7 @@ impl<'a> ChartSeries<'a> {
377387
/// # let mut worksheet = workbook.add_worksheet(None)?;
378388
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
379389
/// # let mut chart = workbook.add_chart(ChartType::Line);
380-
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
390+
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
381391
/// # series1.set_name("=Sheet1!$A$1");
382392
/// series1.set_marker_type(ChartMarkerType::MarkerDiamond);
383393
/// series1.set_marker_size(10);
@@ -405,7 +415,7 @@ impl<'a> ChartSeries<'a> {
405415
/// # let mut worksheet = workbook.add_worksheet(None)?;
406416
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
407417
/// # let mut chart = workbook.add_chart(ChartType::Line);
408-
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
418+
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
409419
/// # series1.set_name("=Sheet1!$A$1");
410420
/// series1.set_marker_type(ChartMarkerType::MarkerDiamond);
411421
/// let mut marker_line = ChartLine::new();
@@ -441,7 +451,7 @@ impl<'a> ChartSeries<'a> {
441451
/// # let mut worksheet = workbook.add_worksheet(None)?;
442452
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
443453
/// # let mut chart = workbook.add_chart(ChartType::Line);
444-
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
454+
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
445455
/// # series1.set_name("=Sheet1!$A$1");
446456
/// series1.set_marker_type(ChartMarkerType::MarkerDiamond);
447457
/// let mut marker_line = ChartLine::new();
@@ -482,7 +492,7 @@ impl<'a> ChartSeries<'a> {
482492
/// # let mut worksheet = workbook.add_worksheet(None)?;
483493
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
484494
/// # let mut chart = workbook.add_chart(ChartType::Line);
485-
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
495+
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
486496
/// # series1.set_name("=Sheet1!$A$1");
487497
/// series1.set_smooth(true);
488498
/// # worksheet.insert_chart(1, 3, &chart)?;
@@ -512,7 +522,7 @@ impl<'a> ChartSeries<'a> {
512522
/// # let mut worksheet = workbook.add_worksheet(None)?;
513523
/// # write_worksheet(&mut worksheet)?; // write worksheet contents
514524
/// # let mut chart = workbook.add_chart(ChartType::Line);
515-
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"));
525+
/// # let mut series1 = chart.add_series(None, Some("=Sheet1!$A$2:$A$6"))?;
516526
/// # series1.set_name("=Sheet1!$A$1");
517527
/// series1.set_marker_type(ChartMarkerType::MarkerDiamond);
518528
/// series1.set_labels();

libxlsxwriter/src/error.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,64 @@ use std::error::Error;
22
use std::ffi;
33
use std::fmt::{self, Display};
44

5-
pub const UNKNOWN_ERROR_CODE: libxlsxwriter_sys::lxw_error = 1000;
6-
pub(crate) const NUMBER_OF_COLUMNS_IS_NOT_MATCHED: libxlsxwriter_sys::lxw_error = 1001;
5+
#[derive(Debug, Clone, PartialEq)]
6+
pub(crate) enum XlsxErrorSource {
7+
LibXlsxWriter(libxlsxwriter_sys::lxw_error),
8+
NumberOfColumnsIsNotMatched,
9+
Unknown,
10+
NulError(std::ffi::NulError),
11+
}
712

813
#[derive(Debug)]
914
pub struct XlsxError {
10-
pub(crate) error: libxlsxwriter_sys::lxw_error,
15+
pub(crate) source: XlsxErrorSource,
1116
}
1217

1318
impl Error for XlsxError {}
1419

1520
impl XlsxError {
1621
pub fn new(error: libxlsxwriter_sys::lxw_error) -> XlsxError {
17-
XlsxError { error }
22+
XlsxError {
23+
source: XlsxErrorSource::LibXlsxWriter(error),
24+
}
25+
}
26+
27+
pub fn unknown_error() -> XlsxError {
28+
XlsxError {
29+
source: XlsxErrorSource::Unknown,
30+
}
1831
}
1932
}
2033

2134
impl Display for XlsxError {
2235
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23-
match self.error {
24-
UNKNOWN_ERROR_CODE => {
36+
match &self.source {
37+
XlsxErrorSource::Unknown => {
2538
write!(f, "Unknown Error")
2639
}
27-
NUMBER_OF_COLUMNS_IS_NOT_MATCHED => {
40+
XlsxErrorSource::NumberOfColumnsIsNotMatched => {
2841
write!(
2942
f,
3043
"Number of columns in an option is not equal to table size"
3144
)
3245
}
33-
_ => unsafe {
34-
match ffi::CStr::from_ptr(libxlsxwriter_sys::lxw_strerror(self.error)).to_str() {
46+
XlsxErrorSource::NulError(e) => {
47+
write!(f, "Null bytes in string: {}", e)
48+
}
49+
XlsxErrorSource::LibXlsxWriter(error) => unsafe {
50+
match ffi::CStr::from_ptr(libxlsxwriter_sys::lxw_strerror(*error)).to_str() {
3551
Ok(error_text) => write!(f, "{}", error_text),
3652
Err(e) => write!(f, "Cannot get xlsx error text: {}", e),
3753
}
3854
},
3955
}
4056
}
4157
}
58+
59+
impl From<std::ffi::NulError> for XlsxError {
60+
fn from(e: std::ffi::NulError) -> Self {
61+
XlsxError {
62+
source: XlsxErrorSource::NulError(e),
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)