@effindomv2/fui-rs 0.1.17 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/worker.rs CHANGED
@@ -108,7 +108,7 @@ impl Worker {
108
108
  if already_started {
109
109
  return self;
110
110
  }
111
- if input.as_bytes().len() > MAX_WORKER_START_INPUT_BYTES {
111
+ if input.len() > MAX_WORKER_START_INPUT_BYTES {
112
112
  let (worker_id, callback) = {
113
113
  let mut inner = self.inner.borrow_mut();
114
114
  inner.started = true;
@@ -186,8 +186,14 @@ fn with_active_worker(worker_id: u32, callback: impl FnOnce(&mut WorkerInner)) {
186
186
  callback(&mut inner);
187
187
  }
188
188
 
189
- #[no_mangle]
190
- pub extern "C" fn __fui_on_worker_progress(worker_id: u32, text_ptr: *const u8, text_len: u32) {
189
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
190
+ /// # Safety
191
+ /// `text_ptr` must be null for an empty message or point to `text_len` readable bytes.
192
+ pub unsafe extern "C" fn __fui_on_worker_progress(
193
+ worker_id: u32,
194
+ text_ptr: *const u8,
195
+ text_len: u32,
196
+ ) {
191
197
  let message = if text_ptr.is_null() || text_len == 0 {
192
198
  String::new()
193
199
  } else {
@@ -204,8 +210,14 @@ pub extern "C" fn __fui_on_worker_progress(worker_id: u32, text_ptr: *const u8,
204
210
  });
205
211
  }
206
212
 
207
- #[no_mangle]
208
- pub extern "C" fn __fui_on_worker_complete(worker_id: u32, text_ptr: *const u8, text_len: u32) {
213
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
214
+ /// # Safety
215
+ /// `text_ptr` must be null for an empty result or point to `text_len` readable bytes.
216
+ pub unsafe extern "C" fn __fui_on_worker_complete(
217
+ worker_id: u32,
218
+ text_ptr: *const u8,
219
+ text_len: u32,
220
+ ) {
209
221
  let result = if text_ptr.is_null() || text_len == 0 {
210
222
  String::new()
211
223
  } else {
@@ -228,8 +240,10 @@ pub extern "C" fn __fui_on_worker_complete(worker_id: u32, text_ptr: *const u8,
228
240
  }
229
241
  }
230
242
 
231
- #[no_mangle]
232
- pub extern "C" fn __fui_on_worker_error(worker_id: u32, text_ptr: *const u8, text_len: u32) {
243
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
244
+ /// # Safety
245
+ /// `text_ptr` must be null for an empty message or point to `text_len` readable bytes.
246
+ pub unsafe extern "C" fn __fui_on_worker_error(worker_id: u32, text_ptr: *const u8, text_len: u32) {
233
247
  let message = if text_ptr.is_null() || text_len == 0 {
234
248
  String::new()
235
249
  } else {
@@ -300,8 +314,10 @@ mod tests {
300
314
  result_clone.replace(event.result);
301
315
  })
302
316
  .start("hello");
303
- super::__fui_on_worker_progress(1, b"25%".as_ptr(), 3);
304
- super::__fui_on_worker_complete(1, b"done".as_ptr(), 4);
317
+ unsafe {
318
+ super::__fui_on_worker_progress(1, b"25%".as_ptr(), 3);
319
+ super::__fui_on_worker_complete(1, b"done".as_ptr(), 4);
320
+ }
305
321
  assert_eq!(&*progress.borrow(), "25%");
306
322
  assert_eq!(&*result.borrow(), "done");
307
323
  }
@@ -42,7 +42,9 @@ fn with_utf8(value: &str, callback: impl FnOnce(usize, u32)) {
42
42
  pub struct WorkerRuntime;
43
43
 
44
44
  impl WorkerRuntime {
45
- pub fn entry_input(input_ptr: usize, input_len: u32) -> String {
45
+ /// # Safety
46
+ /// `input_ptr` must reference at least `input_len` readable bytes when `input_len` is non-zero.
47
+ pub unsafe fn entry_input(input_ptr: usize, input_len: u32) -> String {
46
48
  if input_ptr == 0 || input_len == 0 {
47
49
  return String::new();
48
50
  }
@@ -56,7 +58,7 @@ impl WorkerRuntime {
56
58
  return;
57
59
  }
58
60
  #[cfg(target_arch = "wasm32")]
59
- send_text(progress.as_ref(), |ptr, len| unsafe {
61
+ with_utf8(progress.as_ref(), |ptr, len| unsafe {
60
62
  host_worker_report_progress(ptr, len);
61
63
  });
62
64
  #[cfg(not(target_arch = "wasm32"))]
@@ -69,7 +71,7 @@ impl WorkerRuntime {
69
71
  }
70
72
  WORKER_TERMINAL_SENT.with(|sent| sent.set(true));
71
73
  #[cfg(target_arch = "wasm32")]
72
- send_text(result.as_ref(), |ptr, len| unsafe {
74
+ with_utf8(result.as_ref(), |ptr, len| unsafe {
73
75
  host_worker_complete_string(ptr, len);
74
76
  });
75
77
  #[cfg(not(target_arch = "wasm32"))]
@@ -82,7 +84,7 @@ impl WorkerRuntime {
82
84
  }
83
85
  WORKER_TERMINAL_SENT.with(|sent| sent.set(true));
84
86
  #[cfg(target_arch = "wasm32")]
85
- send_text(message.as_ref(), |ptr, len| unsafe {
87
+ with_utf8(message.as_ref(), |ptr, len| unsafe {
86
88
  host_worker_fail(ptr, len);
87
89
  });
88
90
  #[cfg(not(target_arch = "wasm32"))]
@@ -153,20 +155,62 @@ pub fn worker_text_buffer_size() -> u32 {
153
155
  WORKER_CALLBACK_BUFFER.with(|buffer| buffer.borrow().len() as u32)
154
156
  }
155
157
 
156
- pub fn handle_fetch_complete(
157
- request_id: u32,
158
- ok: bool,
159
- status: i32,
160
- payload_ptr: *const u8,
161
- payload_len: u32,
162
- ) {
163
- crate::fetch::__fui_on_fetch_complete(request_id, ok, status, payload_ptr, payload_len);
158
+ pub fn reset_worker_runtime() {
159
+ WORKER_TERMINAL_SENT.with(|sent| sent.set(false));
164
160
  }
165
161
 
166
- pub fn handle_fetch_error(request_id: u32, payload_ptr: *const u8, payload_len: u32) {
167
- crate::fetch::__fui_on_fetch_error(request_id, payload_ptr, payload_len);
168
- }
162
+ #[cfg(test)]
163
+ mod tests {
164
+ use crate::{fui_worker, WorkerJob, WorkerJobState};
165
+ use std::cell::{Cell, RefCell};
169
166
 
170
- pub fn reset_worker_runtime() {
171
- WORKER_TERMINAL_SENT.with(|sent| sent.set(false));
167
+ thread_local! {
168
+ static START_INPUT: RefCell<String> = const { RefCell::new(String::new()) };
169
+ static RUN_COUNT: Cell<u32> = const { Cell::new(0) };
170
+ }
171
+
172
+ #[derive(Default)]
173
+ struct TestJob {
174
+ state: WorkerJobState,
175
+ }
176
+
177
+ impl WorkerJob for TestJob {
178
+ fn state(&mut self) -> &mut WorkerJobState {
179
+ &mut self.state
180
+ }
181
+
182
+ fn on_start(&mut self, input: String) {
183
+ START_INPUT.with(|value| value.replace(input));
184
+ }
185
+
186
+ fn run(&mut self) {
187
+ let run_count = RUN_COUNT.with(|value| {
188
+ let next = value.get() + 1;
189
+ value.set(next);
190
+ next
191
+ });
192
+ if run_count == 2 {
193
+ self.complete("complete");
194
+ }
195
+ }
196
+ }
197
+
198
+ fui_worker!(test_worker_entry => TestJob);
199
+
200
+ #[test]
201
+ fn worker_macro_keeps_job_state_across_resumes_and_exports_shared_buffer() {
202
+ RUN_COUNT.with(|value| value.set(0));
203
+ START_INPUT.with(|value| value.borrow_mut().clear());
204
+ let input = "start";
205
+
206
+ unsafe {
207
+ test_worker_entry(input.as_ptr() as usize, input.len() as u32);
208
+ test_worker_entry(0, 0);
209
+ }
210
+
211
+ assert_eq!(START_INPUT.with(|value| value.borrow().clone()), "start");
212
+ assert_eq!(RUN_COUNT.with(Cell::get), 2);
213
+ assert_ne!(__fui_worker_text_buffer(), 0);
214
+ assert!(__fui_worker_text_buffer_size() > 0);
215
+ }
172
216
  }