1use wasm_bindgen::prelude::*;
2
3pub mod docx;
4pub mod error;
5pub mod template;
6pub mod utils;
7
8pub use docx::DocxProcessor;
9pub use error::{DocxHandlebarsError, Result};
10pub use template::TemplateEngine;
11
12
13
14pub fn set_panic_hook() {
17 #[cfg(feature = "console_error_panic_hook")]
18 console_error_panic_hook::set_once();
19}
20
21#[wasm_bindgen]
23pub struct DocxHandlebars {
24 processor: DocxProcessor,
25 template_engine: TemplateEngine,
26}
27
28#[wasm_bindgen]
29impl DocxHandlebars {
30 #[wasm_bindgen(constructor)]
32 pub fn new() -> DocxHandlebars {
33 set_panic_hook();
34
35 DocxHandlebars {
36 processor: DocxProcessor::new(),
37 template_engine: TemplateEngine::new(),
38 }
39 }
40
41 #[wasm_bindgen]
43 pub fn load_template(&mut self, bytes: &[u8]) -> std::result::Result<(), JsValue> {
44 self.processor.load_from_bytes(bytes)
45 .map_err(|e| JsValue::from_str(&e.to_string()))
46 }
47
48 #[wasm_bindgen]
50 pub fn render(&self, data_json: &str) -> std::result::Result<Vec<u8>, JsValue> {
51 let data: serde_json::Value = serde_json::from_str(data_json)
52 .map_err(|e| JsValue::from_str(&format!("JSON 解析错误: {}", e)))?;
53
54 let rendered_content = self.template_engine.render_content(
55 self.processor.get_content(),
56 &data
57 ).map_err(|e| JsValue::from_str(&e.to_string()))?;
58
59 self.processor.create_docx_with_content(&rendered_content)
60 .map_err(|e| JsValue::from_str(&e.to_string()))
61 }
62
63 #[wasm_bindgen]
65 pub fn get_template_variables(&self) -> std::result::Result<String, JsValue> {
66 let variables = self.template_engine.extract_variables(self.processor.get_content())
67 .map_err(|e| JsValue::from_str(&e.to_string()))?;
68
69 serde_json::to_string(&variables)
70 .map_err(|e| JsValue::from_str(&format!("序列化错误: {}", e)))
71 }
72}
73
74impl DocxHandlebars {
76 pub fn load_template_bytes(&mut self, bytes: &[u8]) -> Result<()> {
78 self.processor.load_from_bytes(bytes)?;
79 Ok(())
80 }
81
82 pub fn render_with_data<T: serde::Serialize>(&self, data: &T) -> Result<Vec<u8>> {
84 let json_value = serde_json::to_value(data)?;
85 let rendered_content = self.template_engine.render_content(
86 self.processor.get_content(),
87 &json_value
88 )?;
89
90 self.processor.create_docx_with_content(&rendered_content)
91 }
92
93 pub fn extract_template_variables(&self) -> Result<Vec<String>> {
95 self.template_engine.extract_variables(self.processor.get_content())
96 }
97}
98
99impl Default for DocxHandlebars {
100 fn default() -> Self {
101 Self::new()
102 }
103}