Skip to content

Commit e578a6c

Browse files
authored
Merge pull request #10 from tamaroning/feat/rich-string
Impement Rich String
2 parents 4871387 + 0f2c1af commit e578a6c

File tree

9 files changed

+150
-34
lines changed

9 files changed

+150
-34
lines changed

rust/src/wrapper/excel_data.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
66

77
use crate::error::XlsxError;
88

9-
use super::{formula::Formula, url::Url, utils};
9+
use super::{formula::Formula, rich_string::RichString, url::Url, utils};
1010

1111
// We only export the ExcelData type since ExcelDataArray and ExcelDataMatrix are used for
1212
#[wasm_bindgen(typescript_custom_section)]
@@ -15,7 +15,7 @@ const EXCEL_DATA: &'static str = r#"
1515
* Data type that can be written to Excel's cells.
1616
* You can write data to cells via {@link Worksheet#write}.
1717
*/
18-
export type ExcelData = undefined | string | number | boolean | Date | Formula | Url;
18+
export type ExcelData = undefined | string | number | boolean | Date | Formula | Url | RichString;
1919
2020
type ExcelDataArray = ExcelData[];
2121
@@ -108,6 +108,7 @@ pub enum ExcelData {
108108
DateTime(chrono::NaiveDateTime),
109109
Formula(Formula),
110110
Url(Url),
111+
RichString(RichString),
111112
}
112113

113114
impl TryInto<ExcelData> for JsValue {
@@ -136,6 +137,8 @@ impl TryInto<ExcelData> for JsValue {
136137
Ok(ExcelData::Formula(formula))
137138
} else if let Some(url) = utils::url_of_jsval(&self) {
138139
Ok(ExcelData::Url(url))
140+
} else if let Some(rich_string) = utils::rich_string_of_jsval(&self) {
141+
Ok(ExcelData::RichString(rich_string))
139142
} else {
140143
let ctor = Object::get_prototype_of(&self).constructor().name();
141144
Err(XlsxError::Type(format!(
@@ -167,6 +170,12 @@ impl xlsx::IntoExcelData for ExcelData {
167170
ExcelData::DateTime(dt) => worksheet.write_datetime(row, col, dt),
168171
ExcelData::Formula(f) => worksheet.write_formula(row, col, &f.inner),
169172
ExcelData::Url(url) => worksheet.write_url(row, col, &url.inner),
173+
ExcelData::RichString(rich_string) => {
174+
let rich_string = rich_string.lock();
175+
let rich_string: Vec<_> =
176+
rich_string.iter().map(|(f, s)| (f, s.as_str())).collect();
177+
worksheet.write_rich_string(row, col, &rich_string)
178+
}
170179
}
171180
}
172181

@@ -187,6 +196,12 @@ impl xlsx::IntoExcelData for ExcelData {
187196
worksheet.write_formula_with_format(row, col, &f.inner, format)
188197
}
189198
ExcelData::Url(url) => worksheet.write_url_with_format(row, col, &url.inner, format),
199+
ExcelData::RichString(rich_string) => {
200+
let rich_string = rich_string.lock();
201+
let rich_string: Vec<_> =
202+
rich_string.iter().map(|(f, s)| (f, s.as_str())).collect();
203+
worksheet.write_rich_string_with_format(row, col, &rich_string, format)
204+
}
190205
}
191206
}
192207
}

rust/src/wrapper/format.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ impl Format {
188188
}
189189
}
190190

191-
pub(crate) fn get<'a>(&'a self) -> MutexGuard<'a, xlsx::Format> {
191+
pub(crate) fn lock(&self) -> MutexGuard<xlsx::Format> {
192192
self.inner.lock().unwrap()
193193
}
194194

rust/src/wrapper/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod excel_data;
55
mod format;
66
mod formula;
77
mod image;
8+
mod rich_string;
89
mod table;
910
mod url;
1011
mod utils;

rust/src/wrapper/rich_string.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use std::sync::{Arc, Mutex, MutexGuard};
2+
3+
use super::format::Format;
4+
use rust_xlsxwriter as xlsx;
5+
use wasm_bindgen::prelude::*;
6+
7+
/// A rich string is a string that can have multiple formats.
8+
#[derive(Clone)]
9+
#[wasm_bindgen]
10+
pub struct RichString {
11+
inner: Arc<Mutex<Vec<(xlsx::Format, String)>>>,
12+
}
13+
14+
#[wasm_bindgen]
15+
impl RichString {
16+
pub(crate) fn lock(&self) -> MutexGuard<Vec<(xlsx::Format, String)>> {
17+
self.inner.lock().unwrap()
18+
}
19+
20+
/// Create a new RichString struct.
21+
///
22+
/// @returns {RichString} - The rich string object.
23+
#[wasm_bindgen(constructor, skip_jsdoc)]
24+
pub fn new() -> RichString {
25+
RichString {
26+
inner: Arc::new(Mutex::new(vec![])),
27+
}
28+
}
29+
30+
/// Add a new part to the rich string.
31+
#[wasm_bindgen]
32+
pub fn append(&self, format: &Format, string: String) -> RichString {
33+
let mut inner = self.inner.lock().unwrap();
34+
inner.push((format.lock().clone(), string));
35+
RichString {
36+
inner: Arc::clone(&self.inner),
37+
}
38+
}
39+
}

rust/src/wrapper/table.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ impl TableColumn {
162162
#[wasm_bindgen(js_name = "setHeaderFormat", skip_jsdoc)]
163163
pub fn set_header_format(&self, format: &Format) -> TableColumn {
164164
TableColumn {
165-
inner: self.clone().inner.set_header_format(format.get().clone()),
165+
inner: self.clone().inner.set_header_format(format.lock().clone()),
166166
}
167167
}
168168

@@ -183,7 +183,7 @@ impl TableColumn {
183183
#[wasm_bindgen(js_name = "setFormat", skip_jsdoc)]
184184
pub fn set_format(&self, format: &Format) -> TableColumn {
185185
TableColumn {
186-
inner: self.clone().inner.set_format(format.get().clone()),
186+
inner: self.clone().inner.set_format(format.lock().clone()),
187187
}
188188
}
189189

rust/src/wrapper/utils.rs

+7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use wasm_bindgen::prelude::*;
88
use wasm_bindgen::JsCast;
99

1010
use super::formula::Formula;
11+
use super::rich_string::RichString;
1112
use super::url::Url;
1213

1314
fn is_jsdate(obj: &JsValue) -> bool {
@@ -87,3 +88,9 @@ pub fn formula_of_jsval(js: &JsValue) -> Option<Formula> {
8788
pub fn url_of_jsval(js: &JsValue) -> Option<Url> {
8889
generic_of_jsval::<Url>(js, "Url").ok().map(|f| f.clone())
8990
}
91+
92+
pub fn rich_string_of_jsval(js: &JsValue) -> Option<RichString> {
93+
generic_of_jsval::<super::rich_string::RichString>(js, "RichString")
94+
.ok()
95+
.map(|f| f.clone())
96+
}

rust/src/wrapper/worksheet.rs

+59-28
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::wrapper::{
1212
use super::{
1313
excel_data::{JsExcelData, JsExcelDataArray, JsExcelDataMatrix},
1414
formula::Formula,
15+
rich_string::RichString,
1516
url::Url,
1617
};
1718

@@ -282,7 +283,7 @@ impl Worksheet {
282283
let mut book = self.workbook.lock().unwrap();
283284
let sheet = book.worksheet_from_index(self.index).unwrap();
284285
let data: ExcelData = data.try_into()?;
285-
let _ = map_xlsx_error(sheet.write_with_format(row, col, data, &format.get()))?;
286+
let _ = map_xlsx_error(sheet.write_with_format(row, col, data, &format.lock()))?;
286287
Ok(self.clone())
287288
}
288289

@@ -319,7 +320,7 @@ impl Worksheet {
319320
) -> WasmResult<Worksheet> {
320321
let mut book = self.workbook.lock().unwrap();
321322
let sheet = book.worksheet_from_index(self.index).unwrap();
322-
let _ = map_xlsx_error(sheet.write_blank(row, col, &format.get()))?;
323+
let _ = map_xlsx_error(sheet.write_blank(row, col, &format.lock()))?;
323324
Ok(self.clone())
324325
}
325326

@@ -392,7 +393,7 @@ impl Worksheet {
392393
) -> WasmResult<Worksheet> {
393394
let mut book = self.workbook.lock().unwrap();
394395
let sheet = book.worksheet_from_index(self.index).unwrap();
395-
let _ = map_xlsx_error(sheet.write_string_with_format(row, col, string, &format.get()))?;
396+
let _ = map_xlsx_error(sheet.write_string_with_format(row, col, string, &format.lock()))?;
396397
Ok(self.clone())
397398
}
398399

@@ -493,7 +494,7 @@ impl Worksheet {
493494
) -> WasmResult<Worksheet> {
494495
let mut book = self.workbook.lock().unwrap();
495496
let sheet = book.worksheet_from_index(self.index).unwrap();
496-
let _ = map_xlsx_error(sheet.write_number_with_format(row, col, number, &format.get()))?;
497+
let _ = map_xlsx_error(sheet.write_number_with_format(row, col, number, &format.lock()))?;
497498
Ok(self.clone())
498499
}
499500

@@ -552,7 +553,7 @@ impl Worksheet {
552553
) -> WasmResult<Worksheet> {
553554
let mut book = self.workbook.lock().unwrap();
554555
let sheet = book.worksheet_from_index(self.index).unwrap();
555-
let _ = map_xlsx_error(sheet.write_boolean_with_format(row, col, boolean, &format.get()))?;
556+
let _ = map_xlsx_error(sheet.write_boolean_with_format(row, col, boolean, &format.lock()))?;
556557
Ok(self.clone())
557558
}
558559

@@ -627,15 +628,13 @@ impl Worksheet {
627628
let mut book = self.workbook.lock().unwrap();
628629
let sheet = book.worksheet_from_index(self.index).unwrap();
629630
if let Some(dt) = utils::datetime_of_jsval(datetime.clone()) {
630-
let _ = map_xlsx_error(sheet.write_datetime_with_format(row, col, dt, &format.get()))?;
631+
let _ = map_xlsx_error(sheet.write_datetime_with_format(row, col, dt, &format.lock()))?;
631632
Ok(self.clone())
632633
} else {
633634
Err(XlsxError::InvalidDate)
634635
}
635636
}
636637

637-
// TODO: write_rich_string
638-
639638
#[wasm_bindgen(js_name = "writeFormula")]
640639
pub fn write_formula(
641640
&self,
@@ -663,7 +662,7 @@ impl Worksheet {
663662
row,
664663
col,
665664
formula.inner.clone(),
666-
&format.get(),
665+
&format.lock(),
667666
))?;
668667
Ok(self.clone())
669668
}
@@ -691,7 +690,7 @@ impl Worksheet {
691690
) -> WasmResult<Worksheet> {
692691
let mut book = self.workbook.lock().unwrap();
693692
let sheet = book.worksheet_from_index(self.index).unwrap();
694-
let _ = map_xlsx_error(sheet.write_url_with_format(row, col, &link.inner, &format.get()))?;
693+
let _ = map_xlsx_error(sheet.write_url_with_format(row, col, &link.inner, &format.lock()))?;
695694
Ok(self.clone())
696695
}
697696

@@ -727,7 +726,43 @@ impl Worksheet {
727726
&link.inner,
728727
text,
729728
tip,
730-
format.map(|f| f.get().clone()).as_ref(),
729+
format.map(|f| f.lock().clone()).as_ref(),
730+
))?;
731+
Ok(self.clone())
732+
}
733+
734+
#[wasm_bindgen(js_name = "writeRichString")]
735+
pub fn write_rich_string(
736+
&self,
737+
row: xlsx::RowNum,
738+
col: xlsx::ColNum,
739+
rich_string: &RichString,
740+
) -> WasmResult<Worksheet> {
741+
let mut book = self.workbook.lock().unwrap();
742+
let sheet = book.worksheet_from_index(self.index).unwrap();
743+
let rich_string = rich_string.lock();
744+
let rich_string: Vec<_> = rich_string.iter().map(|(f, s)| (f, s.as_str())).collect();
745+
let _ = map_xlsx_error(sheet.write_rich_string(row, col, &rich_string))?;
746+
Ok(self.clone())
747+
}
748+
749+
#[wasm_bindgen(js_name = "writeRichStringWithFormat")]
750+
pub fn write_rich_string_with_format(
751+
&self,
752+
row: xlsx::RowNum,
753+
col: xlsx::ColNum,
754+
rich_string: &RichString,
755+
format: &Format,
756+
) -> WasmResult<Worksheet> {
757+
let mut book = self.workbook.lock().unwrap();
758+
let sheet = book.worksheet_from_index(self.index).unwrap();
759+
let rich_string = rich_string.lock();
760+
let rich_string: Vec<_> = rich_string.iter().map(|(f, s)| (f, s.as_str())).collect();
761+
let _ = map_xlsx_error(sheet.write_rich_string_with_format(
762+
row,
763+
col,
764+
&rich_string,
765+
&format.lock(),
731766
))?;
732767
Ok(self.clone())
733768
}
@@ -757,7 +792,7 @@ impl Worksheet {
757792
let mut book = self.workbook.lock().unwrap();
758793
let sheet = book.worksheet_from_index(self.index).unwrap();
759794
let values: Vec<ExcelData> = values.try_into()?;
760-
let _ = map_xlsx_error(sheet.write_column_with_format(row, col, values, &format.get()))?;
795+
let _ = map_xlsx_error(sheet.write_column_with_format(row, col, values, &format.lock()))?;
761796
Ok(self.clone())
762797
}
763798

@@ -800,7 +835,7 @@ impl Worksheet {
800835
let mut book = self.workbook.lock().unwrap();
801836
let sheet = book.worksheet_from_index(self.index).unwrap();
802837
let values: Vec<ExcelData> = values.try_into()?;
803-
let _ = map_xlsx_error(sheet.write_row_with_format(row, col, values, &format.get()))?;
838+
let _ = map_xlsx_error(sheet.write_row_with_format(row, col, values, &format.lock()))?;
804839
Ok(self.clone())
805840
}
806841

@@ -857,7 +892,7 @@ impl Worksheet {
857892
last_row,
858893
last_col,
859894
formula.inner.clone(),
860-
&format.get(),
895+
&format.lock(),
861896
))?;
862897
Ok(self.clone())
863898
}
@@ -901,7 +936,7 @@ impl Worksheet {
901936
last_row,
902937
last_col,
903938
formula.inner.clone(),
904-
&format.get(),
939+
&format.lock(),
905940
))?;
906941
Ok(self.clone())
907942
}
@@ -945,7 +980,7 @@ impl Worksheet {
945980
last_row,
946981
last_col,
947982
formula.inner.clone(),
948-
&format.get(),
983+
&format.lock(),
949984
))?;
950985
Ok(self.clone())
951986
}
@@ -1017,7 +1052,7 @@ impl Worksheet {
10171052
let mut book = self.workbook.lock().unwrap();
10181053
let sheet = book.worksheet_from_index(self.index).unwrap();
10191054
let _ =
1020-
map_xlsx_error(sheet.embed_image_with_format(row, col, &image.inner, &format.get()))?;
1055+
map_xlsx_error(sheet.embed_image_with_format(row, col, &image.inner, &format.lock()))?;
10211056
Ok(self.clone())
10221057
}
10231058

@@ -1293,23 +1328,19 @@ impl Worksheet {
12931328
last_row,
12941329
last_col,
12951330
value,
1296-
&format.get(),
1331+
&format.lock(),
12971332
))?;
12981333
Ok(self.clone())
12991334
}
1300-
1335+
13011336
#[wasm_bindgen(js_name = "setRowHeight")]
1302-
pub fn set_row_height(
1303-
&mut self,
1304-
row: xlsx::RowNum,
1305-
height: f64,
1306-
) -> WasmResult<Worksheet> {
1337+
pub fn set_row_height(&mut self, row: xlsx::RowNum, height: f64) -> WasmResult<Worksheet> {
13071338
let mut book = self.workbook.lock().unwrap();
13081339
let sheet = book.worksheet_from_index(self.index).unwrap();
13091340
let _ = map_xlsx_error(sheet.set_row_height(row, height))?;
13101341
Ok(self.clone())
13111342
}
1312-
1343+
13131344
#[wasm_bindgen(js_name = "setRowHeightPixels")]
13141345
pub fn set_row_height_pixels(
13151346
&mut self,
@@ -1338,7 +1369,7 @@ impl Worksheet {
13381369
first_col,
13391370
last_row,
13401371
last_col,
1341-
&format.get(),
1372+
&format.lock(),
13421373
))?;
13431374
Ok(self.clone())
13441375
}
@@ -1360,8 +1391,8 @@ impl Worksheet {
13601391
first_col,
13611392
last_row,
13621393
last_col,
1363-
&format.get(),
1364-
&border_format.get(),
1394+
&format.lock(),
1395+
&border_format.lock(),
13651396
))?;
13661397
Ok(self.clone())
13671398
}

test/expected/write_rich_string.xlsx

5.29 KB
Binary file not shown.

0 commit comments

Comments
 (0)