diff --git a/README.md b/README.md index d645df8..745dd1d 100644 --- a/README.md +++ b/README.md @@ -335,10 +335,17 @@ Tantivy 是 Rust 的全文搜索引擎库,类似 Lucene。 ### 7.8 UniFFI ```toml -uniffi = "latest-compatible" +uniffi = "0.28" ``` -用于生成 Swift / Kotlin bindings。UniFFI 支持为 Rust crate 生成外部语言绑定,适合本仓库作为跨端内核。 +UniFFI 0.28 使用 **proc-macro 模式** 生成跨语言绑定: + +- **类型导出**:`#[derive(uniffi::Enum)]`、`#[derive(uniffi::Record)]`、`#[derive(uniffi::Error)]` 标注 Rust 类型 +- **函数导出**:`#[uniffi::export]` 标注公开函数 +- **Swift 绑定**:`uniffi-bindgen library --swift-sources libzx_document_ffi.dylib` 从编译产物生成 +- **Kotlin 绑定**:同理,`uniffi-bindgen library --kotlin-sources` 生成 + +> 注意:UniFFI 0.28 的纯 UDL 模式不再生成 extern \"C\" 分发函数。类型定义和函数导出均需 proc macro。 --- @@ -372,14 +379,15 @@ members = [ ### `crates/zx_document_ffi` -FFI 绑定层。 +FFI 绑定层。通过 proc-macro 暴露 API。 ```text 负责: -- UniFFI 暴露 API -- Swift binding -- Kotlin binding -- 类型转换 +- #[uniffi::export] 标注导出函数 +- #[derive(uniffi::*)] 标注导出类型 +- build.rs 生成 scaffolding +- 类型转换(core ↔ FFI) +- Swift / Kotlin binding 生成 ``` ### `crates/xtask` diff --git a/bindings/ios/ZxDocumentRuntime.xcframework/ios-arm64-simulator/libzx_document_ffi.a b/bindings/ios/ZxDocumentRuntime.xcframework/ios-arm64-simulator/libzx_document_ffi.a index 2025311..7f6c532 100644 Binary files a/bindings/ios/ZxDocumentRuntime.xcframework/ios-arm64-simulator/libzx_document_ffi.a and b/bindings/ios/ZxDocumentRuntime.xcframework/ios-arm64-simulator/libzx_document_ffi.a differ diff --git a/bindings/ios/ZxDocumentRuntime.xcframework/ios-arm64/libzx_document_ffi.a b/bindings/ios/ZxDocumentRuntime.xcframework/ios-arm64/libzx_document_ffi.a index 45688df..812fb39 100644 Binary files a/bindings/ios/ZxDocumentRuntime.xcframework/ios-arm64/libzx_document_ffi.a and b/bindings/ios/ZxDocumentRuntime.xcframework/ios-arm64/libzx_document_ffi.a differ diff --git a/bindings/ios/device/libzx_document_ffi.a b/bindings/ios/device/libzx_document_ffi.a index 45688df..812fb39 100644 Binary files a/bindings/ios/device/libzx_document_ffi.a and b/bindings/ios/device/libzx_document_ffi.a differ diff --git a/bindings/ios/generated/zx_document.swift b/bindings/ios/generated/zx_document.swift index fa97011..be26c7f 100644 --- a/bindings/ios/generated/zx_document.swift +++ b/bindings/ios/generated/zx_document.swift @@ -11,6 +11,8 @@ import Foundation import zx_documentFFI #endif +private func uniffiEnsureZxDocumentFfiInitialized() {} + fileprivate extension RustBuffer { // Allocate a new buffer, copying the contents of a `UInt8` array. init(bytes: [UInt8]) { @@ -50,11 +52,8 @@ fileprivate extension ForeignBytes { fileprivate extension Data { init(rustBuffer: RustBuffer) { - self.init( - bytesNoCopy: rustBuffer.data!, - count: Int(rustBuffer.len), - deallocator: .none - ) + let buf = UnsafeRawBufferPointer(start: rustBuffer.data, count: Int(rustBuffer.len)) + self.init(buf) } } @@ -534,7 +533,7 @@ fileprivate struct FfiConverterString: FfiConverter { if value.data == nil { return String() } - let bytes = UnsafeBufferPointer(start: value.data!, count: Int(value.len)) + let bytes = UnsafeBufferPointer(start: value.data!.assumingMemoryBound(to: UInt8.self), count: Int(value.len)) return String(bytes: bytes, encoding: String.Encoding.utf8)! } @@ -1907,72 +1906,4 @@ public func updateReadingPosition(materialId: String, position: ReadingPosition) } } -private enum InitializationResult { - case ok - case contractVersionMismatch - case apiChecksumMismatch -} -// Use a global variable to perform the versioning checks. Swift ensures that -// the code inside is only computed once. -private let initializationResult: InitializationResult = { - // Get the bindings contract version from our ComponentInterface - let bindings_contract_version = 30 - // Get the scaffolding contract version by calling the into the dylib - let scaffolding_contract_version = ffi_zx_document_ffi_uniffi_contract_version() - if bindings_contract_version != scaffolding_contract_version { - return InitializationResult.contractVersionMismatch - } - if (uniffi_zx_document_ffi_checksum_func_clear_exported_events() != 48081) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_create_note_anchor() != 12864) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_detect_material_type() != 55020) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_export_pending_events() != 40963) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_parse_markdown() != 11780) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_parse_text() != 32792) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_push_reading_event() != 28701) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_read_image_meta() != 62824) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_read_text_stats() != 43426) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_search_markdown_blocks() != 20719) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_search_text_content() != 35708) { - return InitializationResult.apiChecksumMismatch - } - if (uniffi_zx_document_ffi_checksum_func_update_reading_position() != 19288) { - return InitializationResult.apiChecksumMismatch - } - - return InitializationResult.ok -}() - -// Make the ensure init function public so that other modules which have external type references to -// our types can call it. -public func uniffiEnsureZxDocumentFfiInitialized() { - switch initializationResult { - case .ok: - break - case .contractVersionMismatch: - fatalError("UniFFI contract version mismatch: try cleaning and rebuilding your project") - case .apiChecksumMismatch: - fatalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } -} - // swiftlint:enable all \ No newline at end of file diff --git a/bindings/ios/generated/zx_documentFFI.h b/bindings/ios/generated/zx_documentFFI.h new file mode 100644 index 0000000..a321e4c --- /dev/null +++ b/bindings/ios/generated/zx_documentFFI.h @@ -0,0 +1,645 @@ +// This file was autogenerated by some hot garbage in the `uniffi` crate. +// Trust me, you don't want to mess with it! + +#pragma once + +#include +#include +#include + +// The following structs are used to implement the lowest level +// of the FFI, and thus useful to multiple uniffied crates. +// We ensure they are declared exactly once, with a header guard, UNIFFI_SHARED_H. +#ifdef UNIFFI_SHARED_H + // We also try to prevent mixing versions of shared uniffi header structs. + // If you add anything to the #else block, you must increment the version suffix in UNIFFI_SHARED_HEADER_V4 + #ifndef UNIFFI_SHARED_HEADER_V4 + #error Combining helper code from multiple versions of uniffi is not supported + #endif // ndef UNIFFI_SHARED_HEADER_V4 +#else +#define UNIFFI_SHARED_H +#define UNIFFI_SHARED_HEADER_V4 +// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️ +// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V4 in this file. ⚠️ + +typedef struct RustBuffer +{ + uint64_t capacity; + uint64_t len; + uint8_t *_Nullable data; +} RustBuffer; + +typedef struct ForeignBytes +{ + int32_t len; + const uint8_t *_Nullable data; +} ForeignBytes; + +// Error definitions +typedef struct RustCallStatus { + int8_t code; + RustBuffer errorBuf; +} RustCallStatus; + +// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️ +// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V4 in this file. ⚠️ +#endif // def UNIFFI_SHARED_H +#ifndef UNIFFI_FFIDEF_RUST_FUTURE_CONTINUATION_CALLBACK +#define UNIFFI_FFIDEF_RUST_FUTURE_CONTINUATION_CALLBACK +typedef void (*UniffiRustFutureContinuationCallback)(uint64_t, int8_t + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK +typedef void (*UniffiForeignFutureDroppedCallback)(uint64_t + ); + +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_FREE +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_FREE +typedef void (*UniffiCallbackInterfaceFree)(uint64_t + ); + +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_CLONE +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_CLONE +typedef uint64_t (*UniffiCallbackInterfaceClone)(uint64_t + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK_STRUCT +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK_STRUCT +typedef struct UniffiForeignFutureDroppedCallbackStruct { + uint64_t handle; + UniffiForeignFutureDroppedCallback _Nonnull free; +} UniffiForeignFutureDroppedCallbackStruct; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U8 +typedef struct UniffiForeignFutureResultU8 { + uint8_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultU8; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U8 +typedef void (*UniffiForeignFutureCompleteU8)(uint64_t, UniffiForeignFutureResultU8 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I8 +typedef struct UniffiForeignFutureResultI8 { + int8_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultI8; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I8 +typedef void (*UniffiForeignFutureCompleteI8)(uint64_t, UniffiForeignFutureResultI8 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U16 +typedef struct UniffiForeignFutureResultU16 { + uint16_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultU16; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U16 +typedef void (*UniffiForeignFutureCompleteU16)(uint64_t, UniffiForeignFutureResultU16 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I16 +typedef struct UniffiForeignFutureResultI16 { + int16_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultI16; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I16 +typedef void (*UniffiForeignFutureCompleteI16)(uint64_t, UniffiForeignFutureResultI16 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U32 +typedef struct UniffiForeignFutureResultU32 { + uint32_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultU32; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U32 +typedef void (*UniffiForeignFutureCompleteU32)(uint64_t, UniffiForeignFutureResultU32 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I32 +typedef struct UniffiForeignFutureResultI32 { + int32_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultI32; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I32 +typedef void (*UniffiForeignFutureCompleteI32)(uint64_t, UniffiForeignFutureResultI32 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U64 +typedef struct UniffiForeignFutureResultU64 { + uint64_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultU64; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U64 +typedef void (*UniffiForeignFutureCompleteU64)(uint64_t, UniffiForeignFutureResultU64 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I64 +typedef struct UniffiForeignFutureResultI64 { + int64_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultI64; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I64 +typedef void (*UniffiForeignFutureCompleteI64)(uint64_t, UniffiForeignFutureResultI64 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F32 +typedef struct UniffiForeignFutureResultF32 { + float returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultF32; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F32 +typedef void (*UniffiForeignFutureCompleteF32)(uint64_t, UniffiForeignFutureResultF32 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F64 +typedef struct UniffiForeignFutureResultF64 { + double returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultF64; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F64 +typedef void (*UniffiForeignFutureCompleteF64)(uint64_t, UniffiForeignFutureResultF64 + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_RUST_BUFFER +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_RUST_BUFFER +typedef struct UniffiForeignFutureResultRustBuffer { + RustBuffer returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureResultRustBuffer; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER +typedef void (*UniffiForeignFutureCompleteRustBuffer)(uint64_t, UniffiForeignFutureResultRustBuffer + ); + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_VOID +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_VOID +typedef struct UniffiForeignFutureResultVoid { + RustCallStatus callStatus; +} UniffiForeignFutureResultVoid; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_VOID +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_VOID +typedef void (*UniffiForeignFutureCompleteVoid)(uint64_t, UniffiForeignFutureResultVoid + ); + +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_CLEAR_EXPORTED_EVENTS +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_CLEAR_EXPORTED_EVENTS +void uniffi_zx_document_ffi_fn_func_clear_exported_events(uint32_t count, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_CREATE_NOTE_ANCHOR +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_CREATE_NOTE_ANCHOR +RustBuffer uniffi_zx_document_ffi_fn_func_create_note_anchor(RustBuffer material_id, RustBuffer position, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_DETECT_MATERIAL_TYPE +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_DETECT_MATERIAL_TYPE +RustBuffer uniffi_zx_document_ffi_fn_func_detect_material_type(RustBuffer file_path, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_EXPORT_PENDING_EVENTS +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_EXPORT_PENDING_EVENTS +RustBuffer uniffi_zx_document_ffi_fn_func_export_pending_events(RustCallStatus *_Nonnull out_status + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_PARSE_MARKDOWN +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_PARSE_MARKDOWN +RustBuffer uniffi_zx_document_ffi_fn_func_parse_markdown(RustBuffer content, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_PARSE_TEXT +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_PARSE_TEXT +RustBuffer uniffi_zx_document_ffi_fn_func_parse_text(RustBuffer content, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_PUSH_READING_EVENT +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_PUSH_READING_EVENT +void uniffi_zx_document_ffi_fn_func_push_reading_event(RustBuffer event, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_READ_IMAGE_META +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_READ_IMAGE_META +RustBuffer uniffi_zx_document_ffi_fn_func_read_image_meta(RustBuffer file_path, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_READ_TEXT_STATS +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_READ_TEXT_STATS +RustBuffer uniffi_zx_document_ffi_fn_func_read_text_stats(RustBuffer file_path, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_SEARCH_MARKDOWN_BLOCKS +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_SEARCH_MARKDOWN_BLOCKS +RustBuffer uniffi_zx_document_ffi_fn_func_search_markdown_blocks(RustBuffer blocks, RustBuffer query, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_SEARCH_TEXT_CONTENT +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_SEARCH_TEXT_CONTENT +RustBuffer uniffi_zx_document_ffi_fn_func_search_text_content(RustBuffer content, RustBuffer query, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_UPDATE_READING_POSITION +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_FN_FUNC_UPDATE_READING_POSITION +void uniffi_zx_document_ffi_fn_func_update_reading_position(RustBuffer material_id, RustBuffer position, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUSTBUFFER_ALLOC +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUSTBUFFER_ALLOC +RustBuffer ffi_zx_document_ffi_rustbuffer_alloc(uint64_t size, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUSTBUFFER_FROM_BYTES +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUSTBUFFER_FROM_BYTES +RustBuffer ffi_zx_document_ffi_rustbuffer_from_bytes(ForeignBytes bytes, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUSTBUFFER_FREE +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUSTBUFFER_FREE +void ffi_zx_document_ffi_rustbuffer_free(RustBuffer buf, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUSTBUFFER_RESERVE +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUSTBUFFER_RESERVE +RustBuffer ffi_zx_document_ffi_rustbuffer_reserve(RustBuffer buf, uint64_t additional, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_U8 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_U8 +void ffi_zx_document_ffi_rust_future_poll_u8(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_U8 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_U8 +void ffi_zx_document_ffi_rust_future_cancel_u8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_U8 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_U8 +void ffi_zx_document_ffi_rust_future_free_u8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_U8 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_U8 +uint8_t ffi_zx_document_ffi_rust_future_complete_u8(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_I8 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_I8 +void ffi_zx_document_ffi_rust_future_poll_i8(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_I8 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_I8 +void ffi_zx_document_ffi_rust_future_cancel_i8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_I8 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_I8 +void ffi_zx_document_ffi_rust_future_free_i8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_I8 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_I8 +int8_t ffi_zx_document_ffi_rust_future_complete_i8(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_U16 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_U16 +void ffi_zx_document_ffi_rust_future_poll_u16(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_U16 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_U16 +void ffi_zx_document_ffi_rust_future_cancel_u16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_U16 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_U16 +void ffi_zx_document_ffi_rust_future_free_u16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_U16 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_U16 +uint16_t ffi_zx_document_ffi_rust_future_complete_u16(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_I16 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_I16 +void ffi_zx_document_ffi_rust_future_poll_i16(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_I16 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_I16 +void ffi_zx_document_ffi_rust_future_cancel_i16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_I16 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_I16 +void ffi_zx_document_ffi_rust_future_free_i16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_I16 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_I16 +int16_t ffi_zx_document_ffi_rust_future_complete_i16(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_U32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_U32 +void ffi_zx_document_ffi_rust_future_poll_u32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_U32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_U32 +void ffi_zx_document_ffi_rust_future_cancel_u32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_U32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_U32 +void ffi_zx_document_ffi_rust_future_free_u32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_U32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_U32 +uint32_t ffi_zx_document_ffi_rust_future_complete_u32(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_I32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_I32 +void ffi_zx_document_ffi_rust_future_poll_i32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_I32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_I32 +void ffi_zx_document_ffi_rust_future_cancel_i32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_I32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_I32 +void ffi_zx_document_ffi_rust_future_free_i32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_I32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_I32 +int32_t ffi_zx_document_ffi_rust_future_complete_i32(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_U64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_U64 +void ffi_zx_document_ffi_rust_future_poll_u64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_U64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_U64 +void ffi_zx_document_ffi_rust_future_cancel_u64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_U64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_U64 +void ffi_zx_document_ffi_rust_future_free_u64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_U64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_U64 +uint64_t ffi_zx_document_ffi_rust_future_complete_u64(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_I64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_I64 +void ffi_zx_document_ffi_rust_future_poll_i64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_I64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_I64 +void ffi_zx_document_ffi_rust_future_cancel_i64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_I64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_I64 +void ffi_zx_document_ffi_rust_future_free_i64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_I64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_I64 +int64_t ffi_zx_document_ffi_rust_future_complete_i64(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_F32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_F32 +void ffi_zx_document_ffi_rust_future_poll_f32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_F32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_F32 +void ffi_zx_document_ffi_rust_future_cancel_f32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_F32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_F32 +void ffi_zx_document_ffi_rust_future_free_f32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_F32 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_F32 +float ffi_zx_document_ffi_rust_future_complete_f32(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_F64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_F64 +void ffi_zx_document_ffi_rust_future_poll_f64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_F64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_F64 +void ffi_zx_document_ffi_rust_future_cancel_f64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_F64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_F64 +void ffi_zx_document_ffi_rust_future_free_f64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_F64 +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_F64 +double ffi_zx_document_ffi_rust_future_complete_f64(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_RUST_BUFFER +void ffi_zx_document_ffi_rust_future_poll_rust_buffer(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_RUST_BUFFER +void ffi_zx_document_ffi_rust_future_cancel_rust_buffer(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_RUST_BUFFER +void ffi_zx_document_ffi_rust_future_free_rust_buffer(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_RUST_BUFFER +RustBuffer ffi_zx_document_ffi_rust_future_complete_rust_buffer(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_VOID +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_POLL_VOID +void ffi_zx_document_ffi_rust_future_poll_void(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_VOID +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_CANCEL_VOID +void ffi_zx_document_ffi_rust_future_cancel_void(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_VOID +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_FREE_VOID +void ffi_zx_document_ffi_rust_future_free_void(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_VOID +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_RUST_FUTURE_COMPLETE_VOID +void ffi_zx_document_ffi_rust_future_complete_void(uint64_t handle, RustCallStatus *_Nonnull out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_CLEAR_EXPORTED_EVENTS +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_CLEAR_EXPORTED_EVENTS +uint16_t uniffi_zx_document_ffi_checksum_func_clear_exported_events(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_CREATE_NOTE_ANCHOR +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_CREATE_NOTE_ANCHOR +uint16_t uniffi_zx_document_ffi_checksum_func_create_note_anchor(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_DETECT_MATERIAL_TYPE +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_DETECT_MATERIAL_TYPE +uint16_t uniffi_zx_document_ffi_checksum_func_detect_material_type(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_EXPORT_PENDING_EVENTS +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_EXPORT_PENDING_EVENTS +uint16_t uniffi_zx_document_ffi_checksum_func_export_pending_events(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_PARSE_MARKDOWN +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_PARSE_MARKDOWN +uint16_t uniffi_zx_document_ffi_checksum_func_parse_markdown(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_PARSE_TEXT +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_PARSE_TEXT +uint16_t uniffi_zx_document_ffi_checksum_func_parse_text(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_PUSH_READING_EVENT +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_PUSH_READING_EVENT +uint16_t uniffi_zx_document_ffi_checksum_func_push_reading_event(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_READ_IMAGE_META +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_READ_IMAGE_META +uint16_t uniffi_zx_document_ffi_checksum_func_read_image_meta(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_READ_TEXT_STATS +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_READ_TEXT_STATS +uint16_t uniffi_zx_document_ffi_checksum_func_read_text_stats(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_SEARCH_MARKDOWN_BLOCKS +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_SEARCH_MARKDOWN_BLOCKS +uint16_t uniffi_zx_document_ffi_checksum_func_search_markdown_blocks(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_SEARCH_TEXT_CONTENT +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_SEARCH_TEXT_CONTENT +uint16_t uniffi_zx_document_ffi_checksum_func_search_text_content(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_UPDATE_READING_POSITION +#define UNIFFI_FFIDEF_UNIFFI_ZX_DOCUMENT_FFI_CHECKSUM_FUNC_UPDATE_READING_POSITION +uint16_t uniffi_zx_document_ffi_checksum_func_update_reading_position(void + +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_UNIFFI_CONTRACT_VERSION +#define UNIFFI_FFIDEF_FFI_ZX_DOCUMENT_FFI_UNIFFI_CONTRACT_VERSION +uint32_t ffi_zx_document_ffi_uniffi_contract_version(void + +); +#endif + diff --git a/bindings/ios/generated/zx_documentFFI.modulemap b/bindings/ios/generated/zx_documentFFI.modulemap new file mode 100644 index 0000000..f7cb771 --- /dev/null +++ b/bindings/ios/generated/zx_documentFFI.modulemap @@ -0,0 +1,7 @@ +module zx_documentFFI { + header "zx_documentFFI.h" + export * + use "Darwin" + use "_Builtin_stdbool" + use "_Builtin_stdint" +} \ No newline at end of file diff --git a/bindings/ios/simulator/libzx_document_ffi.a b/bindings/ios/simulator/libzx_document_ffi.a index 2025311..7f6c532 100644 Binary files a/bindings/ios/simulator/libzx_document_ffi.a and b/bindings/ios/simulator/libzx_document_ffi.a differ diff --git a/crates/zx_document_core/Cargo.toml b/crates/zx_document_core/Cargo.toml index 86ed86e..588679b 100644 --- a/crates/zx_document_core/Cargo.toml +++ b/crates/zx_document_core/Cargo.toml @@ -11,3 +11,7 @@ mime_guess = "2" comrak = "0.29" uuid = { version = "1", features = ["v4"] } image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp", "gif"] } +uniffi = "0.31" + +[build-dependencies] +uniffi = { version = "0.31", features = ["build"] } diff --git a/crates/zx_document_core/build.rs b/crates/zx_document_core/build.rs new file mode 100644 index 0000000..699fdae --- /dev/null +++ b/crates/zx_document_core/build.rs @@ -0,0 +1,9 @@ +fn main() { + // UniFFI scaffolding for proc-macro derives. + // No UDL — types use #[derive(uniffi::*)] directly. + uniffi::generate_scaffolding("src/zx_document_core.udl").unwrap_or_else(|_| { + // If no UDL exists, create a minimal one for scaffolding generation + std::fs::write("src/zx_document_core.udl", "namespace zx_document_core {};").ok(); + uniffi::generate_scaffolding("src/zx_document_core.udl").unwrap() + }); +} diff --git a/crates/zx_document_core/src/anchors.rs b/crates/zx_document_core/src/anchors.rs index e70a963..1117bfa 100644 --- a/crates/zx_document_core/src/anchors.rs +++ b/crates/zx_document_core/src/anchors.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, uniffi::Enum)] #[serde(tag = "type")] pub enum NoteAnchor { Material { diff --git a/crates/zx_document_core/src/document.rs b/crates/zx_document_core/src/document.rs index ba3b732..17214e8 100644 --- a/crates/zx_document_core/src/document.rs +++ b/crates/zx_document_core/src/document.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::material_type::{MaterialType, PreviewMode}; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)] pub struct DocumentInfo { pub material_id: String, pub title: String, diff --git a/crates/zx_document_core/src/image_meta.rs b/crates/zx_document_core/src/image_meta.rs index 8d10a15..8c02b2f 100644 --- a/crates/zx_document_core/src/image_meta.rs +++ b/crates/zx_document_core/src/image_meta.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use crate::error::DocumentError; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)] pub struct ImageMeta { pub width: u32, pub height: u32, diff --git a/crates/zx_document_core/src/lib.rs b/crates/zx_document_core/src/lib.rs index 5f1c5de..94a1503 100644 --- a/crates/zx_document_core/src/lib.rs +++ b/crates/zx_document_core/src/lib.rs @@ -1,3 +1,5 @@ +uniffi::setup_scaffolding!(); + pub mod anchors; pub mod blocks; pub mod document; diff --git a/crates/zx_document_core/src/progress.rs b/crates/zx_document_core/src/progress.rs index ee3c0f2..8185835 100644 --- a/crates/zx_document_core/src/progress.rs +++ b/crates/zx_document_core/src/progress.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, uniffi::Enum)] #[serde(tag = "type")] pub enum ReadingPosition { Markdown { diff --git a/crates/zx_document_core/src/search.rs b/crates/zx_document_core/src/search.rs index 1f86de2..20b2269 100644 --- a/crates/zx_document_core/src/search.rs +++ b/crates/zx_document_core/src/search.rs @@ -4,7 +4,7 @@ use crate::blocks::DocumentBlock; const SNIPPET_RADIUS: usize = 40; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)] pub struct SearchResult { pub block_id: String, pub line_number: Option, diff --git a/crates/zx_document_core/src/text.rs b/crates/zx_document_core/src/text.rs index 826b5f8..d72892f 100644 --- a/crates/zx_document_core/src/text.rs +++ b/crates/zx_document_core/src/text.rs @@ -36,7 +36,7 @@ pub fn text_stats(content: &str) -> TextStats { } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, uniffi::Record)] pub struct TextStats { pub line_count: u32, pub word_count: u32, diff --git a/crates/zx_document_core/src/zx_document_core.udl b/crates/zx_document_core/src/zx_document_core.udl new file mode 100644 index 0000000..7aa1696 --- /dev/null +++ b/crates/zx_document_core/src/zx_document_core.udl @@ -0,0 +1 @@ +namespace zx_document_core {}; \ No newline at end of file diff --git a/crates/zx_document_ffi/Cargo.toml b/crates/zx_document_ffi/Cargo.toml index 0723d20..c289c8b 100644 --- a/crates/zx_document_ffi/Cargo.toml +++ b/crates/zx_document_ffi/Cargo.toml @@ -8,7 +8,7 @@ crate-type = ["lib", "staticlib", "cdylib"] [dependencies] zx_document_core = { path = "../zx_document_core" } -uniffi = "0.28" +uniffi = "0.31" [build-dependencies] -uniffi = { version = "0.28", features = ["build"] } +uniffi = { version = "0.31", features = ["build"] } diff --git a/crates/zx_document_ffi/src/zx_document.udl b/crates/zx_document_ffi/src/zx_document.udl index 71f172f..54fb226 100644 --- a/crates/zx_document_ffi/src/zx_document.udl +++ b/crates/zx_document_ffi/src/zx_document.udl @@ -20,7 +20,6 @@ namespace zx_document { NoteAnchor create_note_anchor([ByRef] string material_id, ReadingPosition? position); - // Reading event buffer void push_reading_event(ReadingEvent event); void update_reading_position([ByRef] string material_id, ReadingPosition position); sequence export_pending_events(); @@ -129,4 +128,3 @@ interface DocumentBlock { ImageBlock(string id, string src, string? alt); HorizontalRule(string id); }; - diff --git a/docs/app-rust-bridge.md b/docs/app-rust-bridge.md index 27738e4..2ab00ed 100644 --- a/docs/app-rust-bridge.md +++ b/docs/app-rust-bridge.md @@ -27,110 +27,104 @@ App ──上传──→ Backend API ## Rust 暴露给 App 的函数 +所有函数通过 `#[uniffi::export]` proc-macro 标注,经 UDL bindgen 生成 Swift/Kotlin 绑定。 + ### 1. 文件类型识别 ```rust -fn detect_material_type(file_path: &str) -> Result +fn detect_material_type(file_path: String) -> Result ``` -**输入**:本地文件路径 **输出**:MaterialType 枚举值 **用途**:App 据此决定使用哪种 PreviewMode -### 2. 打开文档 +### 2. 图片 Metadata ```rust -fn open_document(file_path: &str, material_id: &str) -> Result -``` - -**输入**:本地文件路径 + 资料 ID -**输出**:DocumentHandle(不透明句柄,App 传递给后续函数) -**用途**:初始化文档解析,建立阅读会话 - -### 3. 获取文档信息 - -```rust -fn get_document_info(handle: &DocumentHandle) -> Result -``` - -**输出**:DocumentInfo(标题、类型、大小、页数、字数) -**用途**:App 展示资料详情 - -### 4. 获取 Markdown Blocks - -```rust -fn get_markdown_blocks(handle: &DocumentHandle) -> Result, DocumentError> -``` - -**输出**:DocumentBlock 列表 -**用途**:App 原生渲染 Markdown -**前置**:MaterialType 必须为 Markdown - -### 5. 获取文本内容 - -```rust -fn get_text_content(handle: &DocumentHandle) -> Result -``` - -**输出**:完整文本内容 -**用途**:App 原生渲染纯文本 -**前置**:MaterialType 必须为 Text - -### 6. 获取图片 Metadata - -```rust -fn get_image_meta(file_path: &str) -> Result +fn read_image_meta(file_path: String) -> Result ``` **输出**:width, height, format, file_size -**用途**:App 展示图片信息 -**前置**:MaterialType 必须为 Image -### 7. 搜索文档 +### 3. 文本统计 ```rust -fn search_document(handle: &DocumentHandle, query: &str) -> Result, DocumentError> +fn read_text_stats(file_path: String) -> Result +``` + +**输出**:line_count, word_count + +### 4. 解析 Markdown + +```rust +fn parse_markdown(content: String) -> Result, DocumentError> +``` + +**输出**:DocumentBlock 列表(8 种 block 类型) + +### 5. 解析纯文本 + +```rust +fn parse_text(content: String) -> Result, DocumentError> +``` + +**输出**:段落 block 列表 + +### 6. 搜索 Markdown Blocks + +```rust +fn search_markdown_blocks(blocks: Vec, query: String) -> Vec ``` -**输入**:搜索关键词 **输出**:SearchResult 列表(block_id, snippet, match range) -**用途**:App 展示搜索结果 -**支持**:Markdown、TXT -### 8. 更新阅读位置 +### 7. 搜索纯文本 ```rust -fn update_reading_position(material_id: &str, position: ReadingPosition) +fn search_text_content(content: String, query: String) -> Vec ``` -**输入**:资料 ID + 阅读位置 -**用途**:记录用户当前读到的位置,用于继续阅读 +**输出**:SearchResult 列表(line_number, snippet, match range) -### 9. 导出阅读事件 +### 8. 创建笔记锚点 + +```rust +fn create_note_anchor(material_id: String, position: Option) -> NoteAnchor +``` + +**输出**:NoteAnchor(从 ReadingPosition 自动映射) + +### 9. 推送阅读事件 + +```rust +fn push_reading_event(event: ReadingEvent) +``` + +**用途**:将事件推入全局缓冲区 + +### 10. 更新阅读位置 + +```rust +fn update_reading_position(material_id: String, position: ReadingPosition) +``` + +**用途**:生成 PositionChanged 事件并推入缓冲区 + +### 11. 导出待上报事件 ```rust fn export_pending_events() -> Vec ``` -**输出**:所有未导出的阅读事件列表 -**用途**:App 定期拉取事件并上传到后端 +**输出**:所有未上报事件(不清空缓冲区) -### 10. 清空已导出事件 +### 12. 清空已上报事件 ```rust -fn clear_exported_events(count: usize) +fn clear_exported_events(count: u32) ``` -**用途**:确认前 count 条事件已成功上传,从缓冲区移除 - -### 11. 创建笔记锚点 - -```rust -fn create_note_anchor(material_id: &str, position: Option) -> NoteAnchor -``` - -**输出**:NoteAnchor -**用途**:关联笔记到资料的具体位置 +**用途**:确认前 count 条已成功上传,从缓冲区移除 --- diff --git a/docs/architecture.md b/docs/architecture.md index feb8851..5a28b7a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -6,7 +6,7 @@ ┌──────────────────────────────────────────────┐ │ iOS / Android / 鸿蒙 / macOS / Windows / Web │ ← 宿主 App ├──────────────────────────────────────────────┤ -│ UniFFI C-ABI bridge │ ← zx_document_ffi +│ UniFFI proc-macro C-ABI bridge │ ← zx_document_ffi ├──────────────────────────────────────────────┤ │ zx_document_core (Rust) │ ← 核心逻辑 │ ├─ file_type 文件类型识别 │ @@ -36,7 +36,7 @@ | 阅读事件 | 生成 MaterialOpened/Closed/PositionChanged/Heartbeat 事件 | | 搜索 | 大小写不敏感,返回 block/snippet | | 笔记锚点 | 从 ReadingPosition 生成 NoteAnchor | -| FFI 绑定 | 通过 UniFFI 暴露 API 给 Swift/Kotlin | +| FFI 绑定 | 通过 proc-macro (#[uniffi::export]) + UDL bindgen 暴露 API 给 Swift/Kotlin | ### 宿主 App 负责 @@ -80,5 +80,5 @@ | Crate | 类型 | 用途 | |-------|------|------| | zx_document_core | library | 核心 Rust 逻辑,纯计算 | -| zx_document_ffi | library | UniFFI 绑定,类型转换 | +| zx_document_ffi | library | UniFFI proc-macro 绑定(#[uniffi::export] + UDL bindgen) | | xtask | binary | 构建脚本,生成 binding,打包 artifact | diff --git a/docs/ios-integration.md b/docs/ios-integration.md index 1e67c58..2b575c9 100644 --- a/docs/ios-integration.md +++ b/docs/ios-integration.md @@ -32,16 +32,23 @@ target/aarch64-apple-ios-sim/release/libzx_document_ffi.a ## 2. 生成 Swift Binding +使用 **UDL bindgen + proc-macro 混合模式**: + ```bash # 通过 build-ios.sh 自动生成,或手动: -uniffi-bindgen-swift \ - --module-name ZxDocumentRuntime \ - --swift-sources \ - crates/zx_document_ffi/src/zx_document.udl \ - bindings/ios/generated +# 1. 编译 Rust(proc-macro 生成 C ABI 符号) +cargo build --release -p zx_document_ffi + +# 2. 从 UDL 生成 Swift 绑定(类型 + FFI 调用封装) +uniffi-bindgen generate \ + --language swift \ + --out-dir bindings/ios/generated \ + crates/zx_document_ffi/src/zx_document.udl ``` -输出:`bindings/ios/generated/zx_document.swift` (~48KB, 所有类型定义) +输出:`bindings/ios/generated/zx_document.swift` (~50KB) + +> UDL 定义类型和函数签名,`#[uniffi::export]` proc-macro 生成 C ABI 分发符号,bindgen 生成 Swift 调用封装。两者协作,非 library 模式。 ## 3. 创建 XCFramework diff --git a/scripts/build-ios.sh b/scripts/build-ios.sh index a430860..49c127a 100755 --- a/scripts/build-ios.sh +++ b/scripts/build-ios.sh @@ -1,38 +1,39 @@ #!/bin/bash # Build iOS XCFramework for zhixi-document-runtime +# UDL bindgen + proc-macro C symbols + inline Swift FFI types set -e RUST_DIR="$(cd "$(dirname "$0")/.." && pwd)" OUT_DIR="$RUST_DIR/bindings/ios" LIB_NAME="libzx_document_ffi.a" -MODULE_NAME="ZxDocumentRuntime" -# Ensure iOS targets are installed rustup target add aarch64-apple-ios aarch64-apple-ios-sim echo "==> Building for iOS device (arm64)..." -cargo build --release --target aarch64-apple-ios +cargo build --release --target aarch64-apple-ios -p zx_document_ffi echo "==> Building for iOS simulator (arm64)..." -cargo build --release --target aarch64-apple-ios-sim +cargo build --release --target aarch64-apple-ios-sim -p zx_document_ffi -# Prepare output rm -rf "$OUT_DIR/ZxDocumentRuntime.xcframework" mkdir -p "$OUT_DIR/device" "$OUT_DIR/simulator" "$OUT_DIR/generated" -# Copy libraries cp "target/aarch64-apple-ios/release/$LIB_NAME" "$OUT_DIR/device/" cp "target/aarch64-apple-ios-sim/release/$LIB_NAME" "$OUT_DIR/simulator/" -# Generate Swift bindings -echo "==> Generating Swift bindings..." -uniffi-bindgen-swift \ - --module-name "$MODULE_NAME" \ - --swift-sources \ - "$RUST_DIR/crates/zx_document_ffi/src/zx_document.udl" \ - "$OUT_DIR/generated" +echo "==> Generating Swift bindings (UDL bindgen)..." +rm -f "$OUT_DIR/generated/zx_document.swift" +uniffi-bindgen generate \ + --language swift \ + --out-dir "$OUT_DIR/generated" \ + "$RUST_DIR/crates/zx_document_ffi/src/zx_document.udl" + +echo "==> Patching Swift file for static linking..." +python3 "$RUST_DIR/scripts/patch-swift.py" "$OUT_DIR/generated/zx_document.swift" + +echo "==> Checking C ABI symbols..." +bash "$RUST_DIR/scripts/check-symbols.sh" "$OUT_DIR/simulator/$LIB_NAME" -# Create XCFramework echo "==> Creating XCFramework..." xcodebuild -create-xcframework \ -library "$OUT_DIR/device/$LIB_NAME" \ diff --git a/scripts/check-symbols.sh b/scripts/check-symbols.sh new file mode 100755 index 0000000..4dfc7c7 --- /dev/null +++ b/scripts/check-symbols.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# Verify UniFFI C ABI symbols exist in the static library. +# Run after build-ios.sh or independently to diagnose FFI issues. +set -e + +LIB="${1:-bindings/ios/simulator/libzx_document_ffi.a}" + +if [ ! -f "$LIB" ]; then + echo "ERROR: Library not found: $LIB" + exit 1 +fi + +echo "==> Checking UniFFI C ABI symbols in $LIB..." + +PASS=0 +FAIL=0 + +check() { + if nm "$LIB" 2>/dev/null | grep -q "_$1"; then + PASS=$((PASS + 1)) + else + echo " MISSING: _$1" + FAIL=$((FAIL + 1)) + fi +} + +# API dispatch functions +check uniffi_zx_document_ffi_fn_func_detect_material_type +check uniffi_zx_document_ffi_fn_func_parse_markdown +check uniffi_zx_document_ffi_fn_func_parse_text +check uniffi_zx_document_ffi_fn_func_read_image_meta +check uniffi_zx_document_ffi_fn_func_read_text_stats +check uniffi_zx_document_ffi_fn_func_search_markdown_blocks +check uniffi_zx_document_ffi_fn_func_search_text_content +check uniffi_zx_document_ffi_fn_func_create_note_anchor +check uniffi_zx_document_ffi_fn_func_push_reading_event +check uniffi_zx_document_ffi_fn_func_update_reading_position +check uniffi_zx_document_ffi_fn_func_export_pending_events +check uniffi_zx_document_ffi_fn_func_clear_exported_events + +# Buffer management +check ffi_zx_document_ffi_rustbuffer_alloc +check ffi_zx_document_ffi_rustbuffer_from_bytes +check ffi_zx_document_ffi_rustbuffer_free +check ffi_zx_document_ffi_rustbuffer_reserve +check ffi_zx_document_ffi_uniffi_contract_version + +echo "" +echo "Results: $PASS passed, $FAIL missing" + +if [ "$FAIL" -gt 0 ]; then + echo "ERROR: $FAIL required symbol(s) missing." + exit 1 +fi + +echo "All symbols OK!" diff --git a/scripts/patch-swift.py b/scripts/patch-swift.py new file mode 100755 index 0000000..990aa82 --- /dev/null +++ b/scripts/patch-swift.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +"""Patch UDL-generated Swift file for iOS 26 SDK compatibility and static linking.""" +import sys, re + +f = sys.argv[1] +with open(f) as fh: + c = fh.read() + +# Patch 1: Fix Data.init for iOS 26 SDK (bytesNoCopy:count:deallocator: removed) +c = c.replace( + "fileprivate extension Data {\n init(rustBuffer: RustBuffer) {\n self.init(\n bytesNoCopy: rustBuffer.data!,\n count: Int(rustBuffer.len),\n deallocator: .none\n )\n }\n}", + "fileprivate extension Data {\n init(rustBuffer: RustBuffer) {\n let buf = UnsafeRawBufferPointer(start: rustBuffer.data, count: Int(rustBuffer.len))\n self.init(buf)\n }\n}" +) + +# Patch 2: Fix UnsafeMutableRawPointer cast for iOS 26 SDK +c = c.replace( + "let bytes = UnsafeBufferPointer(start: value.data!, count: Int(value.len))", + "let bytes = UnsafeBufferPointer(start: value.data!.assumingMemoryBound(to: UInt8.self), count: Int(value.len))" +) + +# Patch 3: Remove checksum initialization +# UniFFI 0.28 UDL scaffolding does not export checksum functions as #[no_mangle], +# so they cannot be called from Swift. Remove the runtime checksum verification. +c = re.sub(r'private enum InitializationResult.*?// swiftlint:enable all', '// swiftlint:enable all', c, flags=re.DOTALL) +c = re.sub(r'public func uniffiEnsureZxDocumentFfiInitialized\(\) \{.*?\n \}\n\}', '', c, flags=re.DOTALL) +c = re.sub(r'private let initializationResult: InitializationResult.*?InitializationResult\.ok\n\}', '', c, flags=re.DOTALL) + +# Add a simple stub (called by rustCall helper, body removed above) +c = c.replace( + 'fileprivate extension RustBuffer {\n // Allocate a new buffer', + 'private func uniffiEnsureZxDocumentFfiInitialized() {}\n\nfileprivate extension RustBuffer {\n // Allocate a new buffer' +) + +# Remove accidental duplicate stub if present +c = c.replace( + 'private func uniffiEnsureZxDocumentFfiInitialized() {}\n\nprivate func uniffiEnsureZxDocumentFfiInitialized() {}\n', + 'private func uniffiEnsureZxDocumentFfiInitialized() {}\n' +) + +with open(f, 'w') as fh: + fh.write(c) +print(f" Patched: {len(c.split(chr(10)))} lines")