feat: #37 Batch1 — detect_material_type/read_image_meta/read_text_stats/parse_text out-pointer FFI
新增 4 个 _separate 函数绕过 RustBuffer struct-passing: - ffi_zx_document_ffi_detect_material_type_separate - ffi_zx_document_ffi_read_image_meta_separate - ffi_zx_document_ffi_read_text_stats_separate - ffi_zx_document_ffi_parse_text_separate 提取 write_result_to_out! 宏和 read_str_input helper 减少样板代码。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
65c9ab8a50
commit
c09caab0e6
@ -242,6 +242,88 @@ fn clear_exported_events(count: u32) {
|
||||
zx_document_core::events::clear_exported_events(count as usize)
|
||||
}
|
||||
|
||||
/// Helper: serialize a Result<T, DocumentError> into out-pointers.
|
||||
/// Generic over T; the RustBuffer methods are accessed via the concrete type
|
||||
/// after the `lower_return` call.
|
||||
macro_rules! write_result_to_out {
|
||||
($result:expr, $out_capacity:ident, $out_len:ident, $out_data:ident, $out_error_code:ident) => {{
|
||||
use uniffi::LowerReturn;
|
||||
match <Result<_, DocumentError> as LowerReturn<UniFfiTag>>::lower_return($result) {
|
||||
Ok(buf) => {
|
||||
unsafe {
|
||||
*$out_capacity = buf.capacity() as u64;
|
||||
*$out_len = buf.len() as u64;
|
||||
*$out_data = buf.data_pointer() as *mut u8;
|
||||
*$out_error_code = 0;
|
||||
}
|
||||
std::mem::forget(buf);
|
||||
}
|
||||
Err(_) => {
|
||||
unsafe { *$out_error_code = -1; }
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Helper: read a UTF-8 string from raw bytes, or set error and return false.
|
||||
unsafe fn read_str_input(len: i32, data: *const u8, out_error_code: *mut i8) -> Option<String> {
|
||||
let slice = std::slice::from_raw_parts(data, len as usize);
|
||||
match std::str::from_utf8(slice) {
|
||||
Ok(s) => Some(s.to_string()),
|
||||
Err(_) => { *out_error_code = -1; None },
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Batch 1 out-pointer functions: String input → Result<T, E> output ───
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_zx_document_ffi_detect_material_type_separate(
|
||||
len: i32, data: *const u8,
|
||||
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||
) {
|
||||
let file_path = match unsafe { read_str_input(len, data, out_error_code) } {
|
||||
Some(s) => s, None => return,
|
||||
};
|
||||
let result = crate::detect_material_type(file_path);
|
||||
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_zx_document_ffi_read_image_meta_separate(
|
||||
len: i32, data: *const u8,
|
||||
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||
) {
|
||||
let file_path = match unsafe { read_str_input(len, data, out_error_code) } {
|
||||
Some(s) => s, None => return,
|
||||
};
|
||||
let result = crate::read_image_meta(file_path);
|
||||
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_zx_document_ffi_read_text_stats_separate(
|
||||
len: i32, data: *const u8,
|
||||
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||
) {
|
||||
let file_path = match unsafe { read_str_input(len, data, out_error_code) } {
|
||||
Some(s) => s, None => return,
|
||||
};
|
||||
let result = crate::read_text_stats(file_path);
|
||||
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_zx_document_ffi_parse_text_separate(
|
||||
len: i32, data: *const u8,
|
||||
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||
) {
|
||||
let content = match unsafe { read_str_input(len, data, out_error_code) } {
|
||||
Some(s) => s, None => return,
|
||||
};
|
||||
let result = crate::parse_text(content);
|
||||
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
||||
}
|
||||
|
||||
// Reverse conversion: FFI DocumentBlock → core DocumentBlock, used by search.
|
||||
fn core_block_from_ffi(block: DocumentBlock) -> core_blocks::DocumentBlock {
|
||||
match block {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user