inputx_pinyin_wasm/
lib.rs1use wasm_bindgen::prelude::*;
27
28use inputx_pinyin::{L0Snapshot, PinyinDict, char_to_pinyin};
29
30#[wasm_bindgen]
34pub struct PinyinEngine {
35 dict: PinyinDict,
36}
37
38#[wasm_bindgen]
39impl PinyinEngine {
40 #[wasm_bindgen(constructor)]
43 pub fn new() -> PinyinEngine {
44 Self {
45 dict: PinyinDict::embedded(),
46 }
47 }
48
49 #[wasm_bindgen(getter)]
51 pub fn len(&self) -> usize {
52 self.dict.len()
53 }
54
55 #[wasm_bindgen(getter, js_name = isEmpty)]
57 pub fn is_empty(&self) -> bool {
58 self.dict.is_empty()
59 }
60
61 pub fn lookup(&self, pinyin: &str) -> js_sys::Array {
63 let arr = js_sys::Array::new();
64 for word in self.dict.lookup(pinyin) {
65 arr.push(&JsValue::from_str(&word));
66 }
67 arr
68 }
69
70 #[wasm_bindgen(js_name = prefix)]
72 pub fn prefix_lookup(&self, prefix: &str) -> js_sys::Array {
73 let arr = js_sys::Array::new();
74 for (pinyin, word) in self.dict.prefix(prefix) {
75 let obj = js_sys::Object::new();
76 let _ = js_sys::Reflect::set(&obj, &"pinyin".into(), &JsValue::from_str(&pinyin));
77 let _ = js_sys::Reflect::set(&obj, &"word".into(), &JsValue::from_str(&word));
78 arr.push(&obj);
79 }
80 arr
81 }
82
83 pub fn encode(&self, ch: &str) -> js_sys::Array {
85 let arr = js_sys::Array::new();
86 let Some(c) = ch.chars().next() else {
87 return arr;
88 };
89 for r in char_to_pinyin(c) {
90 arr.push(&JsValue::from_str(&r));
91 }
92 arr
93 }
94
95 #[wasm_bindgen(js_name = recordPick)]
104 pub fn record_pick(&self, pinyin: &str, word: &str) -> bool {
105 self.dict.record_pick(pinyin, word)
106 }
107
108 pub fn pin(&self, pinyin: &str, word: &str) -> bool {
111 self.dict.pin(pinyin, word)
112 }
113
114 pub fn forget(&self, pinyin: &str) -> bool {
116 self.dict.forget(pinyin)
117 }
118
119 #[wasm_bindgen(js_name = l0PinCount, getter)]
121 pub fn l0_pin_count(&self) -> usize {
122 self.dict.l0_pin_count()
123 }
124
125 #[wasm_bindgen(js_name = l0PendingCount, getter)]
127 pub fn l0_pending_count(&self) -> usize {
128 self.dict.l0_pending_count()
129 }
130
131 #[wasm_bindgen(js_name = exportL0)]
138 pub fn export_l0(&self) -> JsValue {
139 let snap = self.dict.export_l0();
140 let obj = js_sys::Object::new();
141
142 let pins = js_sys::Array::new();
143 for (p, w) in &snap.pins {
144 let pair = js_sys::Array::new();
145 pair.push(&JsValue::from_str(p));
146 pair.push(&JsValue::from_str(w));
147 pins.push(&pair);
148 }
149 let _ = js_sys::Reflect::set(&obj, &"pins".into(), &pins);
150
151 let counts = js_sys::Array::new();
152 for (p, w, n) in &snap.pick_counts {
153 let triple = js_sys::Array::new();
154 triple.push(&JsValue::from_str(p));
155 triple.push(&JsValue::from_str(w));
156 triple.push(&JsValue::from_f64(*n as f64));
157 counts.push(&triple);
158 }
159 let _ = js_sys::Reflect::set(&obj, &"pickCounts".into(), &counts);
160
161 obj.into()
162 }
163
164 #[wasm_bindgen(js_name = importL0)]
168 pub fn import_l0(&self, state: JsValue) -> usize {
169 let Some(obj) = state.dyn_ref::<js_sys::Object>() else {
170 return 0;
171 };
172 let snap = parse_snapshot(obj);
173 self.dict.import_l0(snap)
174 }
175}
176
177impl Default for PinyinEngine {
178 fn default() -> Self {
179 Self::new()
180 }
181}
182
183fn parse_snapshot(obj: &js_sys::Object) -> L0Snapshot {
184 let pins = js_sys::Reflect::get(obj, &"pins".into())
185 .ok()
186 .and_then(|v| v.dyn_into::<js_sys::Array>().ok())
187 .map(|arr| {
188 arr.iter()
189 .filter_map(|pair| {
190 let pair: js_sys::Array = pair.dyn_into().ok()?;
191 let p = pair.get(0).as_string()?;
192 let w = pair.get(1).as_string()?;
193 Some((p, w))
194 })
195 .collect()
196 })
197 .unwrap_or_default();
198
199 let pick_counts = js_sys::Reflect::get(obj, &"pickCounts".into())
200 .ok()
201 .and_then(|v| v.dyn_into::<js_sys::Array>().ok())
202 .map(|arr| {
203 arr.iter()
204 .filter_map(|triple| {
205 let triple: js_sys::Array = triple.dyn_into().ok()?;
206 let p = triple.get(0).as_string()?;
207 let w = triple.get(1).as_string()?;
208 let n = triple.get(2).as_f64()? as u32;
209 Some((p, w, n))
210 })
211 .collect()
212 })
213 .unwrap_or_default();
214
215 L0Snapshot { pins, pick_counts }
216}