From 4e42b286d95adfa227536f78e59ace3fc116e62a Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Tue, 15 Oct 2024 17:05:39 -0700 Subject: [PATCH] dump the new schema --- library/src/main/java/libxmtp-version.txt | 4 +- library/src/main/java/xmtpv3.kt | 3003 ++++++++++++--------- 2 files changed, 1694 insertions(+), 1313 deletions(-) diff --git a/library/src/main/java/libxmtp-version.txt b/library/src/main/java/libxmtp-version.txt index 8e2ce39b5..5a03a5889 100644 --- a/library/src/main/java/libxmtp-version.txt +++ b/library/src/main/java/libxmtp-version.txt @@ -1,3 +1,3 @@ -Version: 137062e8 +Version: f4d22fb8 Branch: main -Date: 2024-10-08 19:58:58 +0000 +Date: 2024-10-15 21:05:51 +0000 diff --git a/library/src/main/java/xmtpv3.kt b/library/src/main/java/xmtpv3.kt index 7e7f10b10..80efba141 100644 --- a/library/src/main/java/xmtpv3.kt +++ b/library/src/main/java/xmtpv3.kt @@ -49,8 +49,10 @@ open class RustBuffer : Structure() { // When dealing with these fields, make sure to call `toULong()`. @JvmField var capacity: Long = 0 + @JvmField var len: Long = 0 + @JvmField var data: Pointer? = null @@ -135,6 +137,7 @@ class RustBufferByReference : ByReference(16) { open class ForeignBytes : Structure() { @JvmField var len: Int = 0 + @JvmField var data: Pointer? = null @@ -223,6 +226,7 @@ internal const val UNIFFI_CALL_UNEXPECTED_ERROR = 2.toByte() internal open class UniffiRustCallStatus : Structure() { @JvmField var code: Byte = 0 + @JvmField var error_buf: RustBuffer.ByValue = RustBuffer.ByValue() @@ -860,221 +864,245 @@ internal interface UniffiLib : Library { } } - fun uniffi_xmtpv3_fn_clone_fficonversations( - `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, - ): Pointer - - fun uniffi_xmtpv3_fn_free_fficonversations( - `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, - ): Unit - - fun uniffi_xmtpv3_fn_method_fficonversations_create_dm( - `ptr`: Pointer, `accountAddress`: RustBuffer.ByValue, - ): Long - - fun uniffi_xmtpv3_fn_method_fficonversations_create_group( - `ptr`: Pointer, `accountAddresses`: RustBuffer.ByValue, `opts`: RustBuffer.ByValue, - ): Long - - fun uniffi_xmtpv3_fn_method_fficonversations_list( - `ptr`: Pointer, `opts`: RustBuffer.ByValue, - ): Long - - fun uniffi_xmtpv3_fn_method_fficonversations_process_streamed_welcome_message( - `ptr`: Pointer, `envelopeBytes`: RustBuffer.ByValue, - ): Long - - fun uniffi_xmtpv3_fn_method_fficonversations_stream( - `ptr`: Pointer, `callback`: Long, - ): Long - - fun uniffi_xmtpv3_fn_method_fficonversations_stream_all_messages( - `ptr`: Pointer, `messageCallback`: Long, - ): Long - - fun uniffi_xmtpv3_fn_method_fficonversations_sync( - `ptr`: Pointer, - ): Long - - fun uniffi_xmtpv3_fn_method_fficonversations_sync_all_groups( - `ptr`: Pointer, - ): Long - - fun uniffi_xmtpv3_fn_clone_ffigroup( + fun uniffi_xmtpv3_fn_clone_fficonversation( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Pointer - fun uniffi_xmtpv3_fn_free_ffigroup( + fun uniffi_xmtpv3_fn_free_fficonversation( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Unit - fun uniffi_xmtpv3_fn_method_ffigroup_add_admin( + fun uniffi_xmtpv3_fn_method_fficonversation_add_admin( `ptr`: Pointer, `inboxId`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_add_members( + fun uniffi_xmtpv3_fn_method_fficonversation_add_members( `ptr`: Pointer, `accountAddresses`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_add_members_by_inbox_id( + fun uniffi_xmtpv3_fn_method_fficonversation_add_members_by_inbox_id( `ptr`: Pointer, `inboxIds`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_add_super_admin( + fun uniffi_xmtpv3_fn_method_fficonversation_add_super_admin( `ptr`: Pointer, `inboxId`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_added_by_inbox_id( + fun uniffi_xmtpv3_fn_method_fficonversation_added_by_inbox_id( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_admin_list( + fun uniffi_xmtpv3_fn_method_fficonversation_admin_list( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_consent_state( + fun uniffi_xmtpv3_fn_method_fficonversation_consent_state( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_created_at_ns( + fun uniffi_xmtpv3_fn_method_fficonversation_created_at_ns( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_find_messages( + fun uniffi_xmtpv3_fn_method_fficonversation_find_messages( `ptr`: Pointer, `opts`: RustBuffer.ByValue, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_group_description( + fun uniffi_xmtpv3_fn_method_fficonversation_group_description( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_group_image_url_square( + fun uniffi_xmtpv3_fn_method_fficonversation_group_image_url_square( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_group_metadata( + fun uniffi_xmtpv3_fn_method_fficonversation_group_metadata( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Pointer - fun uniffi_xmtpv3_fn_method_ffigroup_group_name( + fun uniffi_xmtpv3_fn_method_fficonversation_group_name( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_group_permissions( + fun uniffi_xmtpv3_fn_method_fficonversation_group_permissions( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Pointer - fun uniffi_xmtpv3_fn_method_ffigroup_group_pinned_frame_url( + fun uniffi_xmtpv3_fn_method_fficonversation_group_pinned_frame_url( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_id( + fun uniffi_xmtpv3_fn_method_fficonversation_id( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_is_active( + fun uniffi_xmtpv3_fn_method_fficonversation_is_active( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Byte - fun uniffi_xmtpv3_fn_method_ffigroup_is_admin( + fun uniffi_xmtpv3_fn_method_fficonversation_is_admin( `ptr`: Pointer, `inboxId`: RustBuffer.ByValue, uniffi_out_err: UniffiRustCallStatus, ): Byte - fun uniffi_xmtpv3_fn_method_ffigroup_is_super_admin( + fun uniffi_xmtpv3_fn_method_fficonversation_is_super_admin( `ptr`: Pointer, `inboxId`: RustBuffer.ByValue, uniffi_out_err: UniffiRustCallStatus, ): Byte - fun uniffi_xmtpv3_fn_method_ffigroup_list_members( + fun uniffi_xmtpv3_fn_method_fficonversation_list_members( `ptr`: Pointer, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_process_streamed_group_message( + fun uniffi_xmtpv3_fn_method_fficonversation_process_streamed_conversation_message( `ptr`: Pointer, `envelopeBytes`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_publish_messages( + fun uniffi_xmtpv3_fn_method_fficonversation_publish_messages( `ptr`: Pointer, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_remove_admin( + fun uniffi_xmtpv3_fn_method_fficonversation_remove_admin( `ptr`: Pointer, `inboxId`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_remove_members( + fun uniffi_xmtpv3_fn_method_fficonversation_remove_members( `ptr`: Pointer, `accountAddresses`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_remove_members_by_inbox_id( + fun uniffi_xmtpv3_fn_method_fficonversation_remove_members_by_inbox_id( `ptr`: Pointer, `inboxIds`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_remove_super_admin( + fun uniffi_xmtpv3_fn_method_fficonversation_remove_super_admin( `ptr`: Pointer, `inboxId`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_send( + fun uniffi_xmtpv3_fn_method_fficonversation_send( `ptr`: Pointer, `contentBytes`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_send_optimistic( + fun uniffi_xmtpv3_fn_method_fficonversation_send_optimistic( `ptr`: Pointer, `contentBytes`: RustBuffer.ByValue, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_stream( + fun uniffi_xmtpv3_fn_method_fficonversation_stream( `ptr`: Pointer, `messageCallback`: Long, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_super_admin_list( + fun uniffi_xmtpv3_fn_method_fficonversation_super_admin_list( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroup_sync( + fun uniffi_xmtpv3_fn_method_fficonversation_sync( `ptr`: Pointer, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_update_consent_state( + fun uniffi_xmtpv3_fn_method_fficonversation_update_consent_state( `ptr`: Pointer, `state`: RustBuffer.ByValue, uniffi_out_err: UniffiRustCallStatus, ): Unit - fun uniffi_xmtpv3_fn_method_ffigroup_update_group_description( + fun uniffi_xmtpv3_fn_method_fficonversation_update_group_description( `ptr`: Pointer, `groupDescription`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_update_group_image_url_square( + fun uniffi_xmtpv3_fn_method_fficonversation_update_group_image_url_square( `ptr`: Pointer, `groupImageUrlSquare`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_update_group_name( + fun uniffi_xmtpv3_fn_method_fficonversation_update_group_name( `ptr`: Pointer, `groupName`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_update_group_pinned_frame_url( + fun uniffi_xmtpv3_fn_method_fficonversation_update_group_pinned_frame_url( `ptr`: Pointer, `pinnedFrameUrl`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffigroup_update_permission_policy( + fun uniffi_xmtpv3_fn_method_fficonversation_update_permission_policy( `ptr`: Pointer, `permissionUpdateType`: RustBuffer.ByValue, `permissionPolicyOption`: RustBuffer.ByValue, `metadataField`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_clone_ffigroupmetadata( + fun uniffi_xmtpv3_fn_clone_fficonversationmetadata( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Pointer - fun uniffi_xmtpv3_fn_free_ffigroupmetadata( + fun uniffi_xmtpv3_fn_free_fficonversationmetadata( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Unit - fun uniffi_xmtpv3_fn_method_ffigroupmetadata_conversation_type( + fun uniffi_xmtpv3_fn_method_fficonversationmetadata_conversation_type( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue - fun uniffi_xmtpv3_fn_method_ffigroupmetadata_creator_inbox_id( + fun uniffi_xmtpv3_fn_method_fficonversationmetadata_creator_inbox_id( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue + fun uniffi_xmtpv3_fn_clone_fficonversations( + `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, + ): Pointer + + fun uniffi_xmtpv3_fn_free_fficonversations( + `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, + ): Unit + + fun uniffi_xmtpv3_fn_method_fficonversations_create_dm( + `ptr`: Pointer, `accountAddress`: RustBuffer.ByValue, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_create_group( + `ptr`: Pointer, `accountAddresses`: RustBuffer.ByValue, `opts`: RustBuffer.ByValue, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_list( + `ptr`: Pointer, `opts`: RustBuffer.ByValue, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_list_dms( + `ptr`: Pointer, `opts`: RustBuffer.ByValue, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_list_groups( + `ptr`: Pointer, `opts`: RustBuffer.ByValue, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_process_streamed_welcome_message( + `ptr`: Pointer, `envelopeBytes`: RustBuffer.ByValue, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_stream( + `ptr`: Pointer, `callback`: Long, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_stream_all_dm_messages( + `ptr`: Pointer, `messageCallback`: Long, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_stream_all_group_messages( + `ptr`: Pointer, `messageCallback`: Long, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_stream_all_messages( + `ptr`: Pointer, `messageCallback`: Long, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_stream_dms( + `ptr`: Pointer, `callback`: Long, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_stream_groups( + `ptr`: Pointer, `callback`: Long, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_sync( + `ptr`: Pointer, + ): Long + + fun uniffi_xmtpv3_fn_method_fficonversations_sync_all_conversations( + `ptr`: Pointer, + ): Long + fun uniffi_xmtpv3_fn_clone_ffigrouppermissions( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Pointer @@ -1205,6 +1233,10 @@ internal interface UniffiLib : Library { `newWalletAddress`: RustBuffer.ByValue, ): Long + fun uniffi_xmtpv3_fn_method_ffixmtpclient_addresses_from_inbox_id( + `ptr`: Pointer, `refreshFromNetwork`: Byte, `inboxIds`: RustBuffer.ByValue, + ): Long + fun uniffi_xmtpv3_fn_method_ffixmtpclient_apply_signature_request( `ptr`: Pointer, `signatureRequest`: Pointer, ): Long @@ -1213,6 +1245,10 @@ internal interface UniffiLib : Library { `ptr`: Pointer, `accountAddresses`: RustBuffer.ByValue, ): Long + fun uniffi_xmtpv3_fn_method_ffixmtpclient_conversation( + `ptr`: Pointer, `conversationId`: RustBuffer.ByValue, uniffi_out_err: UniffiRustCallStatus, + ): Pointer + fun uniffi_xmtpv3_fn_method_ffixmtpclient_conversations( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): Pointer @@ -1221,6 +1257,10 @@ internal interface UniffiLib : Library { `ptr`: Pointer, ): Long + fun uniffi_xmtpv3_fn_method_ffixmtpclient_dm_conversation( + `ptr`: Pointer, `targetInboxId`: RustBuffer.ByValue, uniffi_out_err: UniffiRustCallStatus, + ): Pointer + fun uniffi_xmtpv3_fn_method_ffixmtpclient_find_inbox_id( `ptr`: Pointer, `address`: RustBuffer.ByValue, ): Long @@ -1233,10 +1273,6 @@ internal interface UniffiLib : Library { `ptr`: Pointer, `inboxId`: RustBuffer.ByValue, ): Long - fun uniffi_xmtpv3_fn_method_ffixmtpclient_group( - `ptr`: Pointer, `groupId`: RustBuffer.ByValue, uniffi_out_err: UniffiRustCallStatus, - ): Pointer - fun uniffi_xmtpv3_fn_method_ffixmtpclient_inbox_id( `ptr`: Pointer, uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue @@ -1667,145 +1703,163 @@ internal interface UniffiLib : Library { fun uniffi_xmtpv3_checksum_func_verify_k256_sha256( ): Short - fun uniffi_xmtpv3_checksum_method_fficonversations_create_dm( + fun uniffi_xmtpv3_checksum_method_fficonversation_add_admin( ): Short - fun uniffi_xmtpv3_checksum_method_fficonversations_create_group( + fun uniffi_xmtpv3_checksum_method_fficonversation_add_members( ): Short - fun uniffi_xmtpv3_checksum_method_fficonversations_list( + fun uniffi_xmtpv3_checksum_method_fficonversation_add_members_by_inbox_id( ): Short - fun uniffi_xmtpv3_checksum_method_fficonversations_process_streamed_welcome_message( + fun uniffi_xmtpv3_checksum_method_fficonversation_add_super_admin( ): Short - fun uniffi_xmtpv3_checksum_method_fficonversations_stream( + fun uniffi_xmtpv3_checksum_method_fficonversation_added_by_inbox_id( ): Short - fun uniffi_xmtpv3_checksum_method_fficonversations_stream_all_messages( + fun uniffi_xmtpv3_checksum_method_fficonversation_admin_list( ): Short - fun uniffi_xmtpv3_checksum_method_fficonversations_sync( + fun uniffi_xmtpv3_checksum_method_fficonversation_consent_state( + ): Short + + fun uniffi_xmtpv3_checksum_method_fficonversation_created_at_ns( + ): Short + + fun uniffi_xmtpv3_checksum_method_fficonversation_find_messages( + ): Short + + fun uniffi_xmtpv3_checksum_method_fficonversation_group_description( + ): Short + + fun uniffi_xmtpv3_checksum_method_fficonversation_group_image_url_square( + ): Short + + fun uniffi_xmtpv3_checksum_method_fficonversation_group_metadata( + ): Short + + fun uniffi_xmtpv3_checksum_method_fficonversation_group_name( ): Short - fun uniffi_xmtpv3_checksum_method_fficonversations_sync_all_groups( + fun uniffi_xmtpv3_checksum_method_fficonversation_group_permissions( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_add_admin( + fun uniffi_xmtpv3_checksum_method_fficonversation_group_pinned_frame_url( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_add_members( + fun uniffi_xmtpv3_checksum_method_fficonversation_id( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_add_members_by_inbox_id( + fun uniffi_xmtpv3_checksum_method_fficonversation_is_active( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_add_super_admin( + fun uniffi_xmtpv3_checksum_method_fficonversation_is_admin( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_added_by_inbox_id( + fun uniffi_xmtpv3_checksum_method_fficonversation_is_super_admin( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_admin_list( + fun uniffi_xmtpv3_checksum_method_fficonversation_list_members( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_consent_state( + fun uniffi_xmtpv3_checksum_method_fficonversation_process_streamed_conversation_message( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_created_at_ns( + fun uniffi_xmtpv3_checksum_method_fficonversation_publish_messages( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_find_messages( + fun uniffi_xmtpv3_checksum_method_fficonversation_remove_admin( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_group_description( + fun uniffi_xmtpv3_checksum_method_fficonversation_remove_members( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_group_image_url_square( + fun uniffi_xmtpv3_checksum_method_fficonversation_remove_members_by_inbox_id( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_group_metadata( + fun uniffi_xmtpv3_checksum_method_fficonversation_remove_super_admin( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_group_name( + fun uniffi_xmtpv3_checksum_method_fficonversation_send( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_group_permissions( + fun uniffi_xmtpv3_checksum_method_fficonversation_send_optimistic( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_group_pinned_frame_url( + fun uniffi_xmtpv3_checksum_method_fficonversation_stream( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_id( + fun uniffi_xmtpv3_checksum_method_fficonversation_super_admin_list( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_is_active( + fun uniffi_xmtpv3_checksum_method_fficonversation_sync( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_is_admin( + fun uniffi_xmtpv3_checksum_method_fficonversation_update_consent_state( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_is_super_admin( + fun uniffi_xmtpv3_checksum_method_fficonversation_update_group_description( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_list_members( + fun uniffi_xmtpv3_checksum_method_fficonversation_update_group_image_url_square( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_process_streamed_group_message( + fun uniffi_xmtpv3_checksum_method_fficonversation_update_group_name( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_publish_messages( + fun uniffi_xmtpv3_checksum_method_fficonversation_update_group_pinned_frame_url( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_remove_admin( + fun uniffi_xmtpv3_checksum_method_fficonversation_update_permission_policy( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_remove_members( + fun uniffi_xmtpv3_checksum_method_fficonversationmetadata_conversation_type( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_remove_members_by_inbox_id( + fun uniffi_xmtpv3_checksum_method_fficonversationmetadata_creator_inbox_id( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_remove_super_admin( + fun uniffi_xmtpv3_checksum_method_fficonversations_create_dm( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_send( + fun uniffi_xmtpv3_checksum_method_fficonversations_create_group( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_send_optimistic( + fun uniffi_xmtpv3_checksum_method_fficonversations_list( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_stream( + fun uniffi_xmtpv3_checksum_method_fficonversations_list_dms( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_super_admin_list( + fun uniffi_xmtpv3_checksum_method_fficonversations_list_groups( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_sync( + fun uniffi_xmtpv3_checksum_method_fficonversations_process_streamed_welcome_message( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_update_consent_state( + fun uniffi_xmtpv3_checksum_method_fficonversations_stream( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_update_group_description( + fun uniffi_xmtpv3_checksum_method_fficonversations_stream_all_dm_messages( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_update_group_image_url_square( + fun uniffi_xmtpv3_checksum_method_fficonversations_stream_all_group_messages( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_update_group_name( + fun uniffi_xmtpv3_checksum_method_fficonversations_stream_all_messages( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_update_group_pinned_frame_url( + fun uniffi_xmtpv3_checksum_method_fficonversations_stream_dms( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroup_update_permission_policy( + fun uniffi_xmtpv3_checksum_method_fficonversations_stream_groups( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroupmetadata_conversation_type( + fun uniffi_xmtpv3_checksum_method_fficonversations_sync( ): Short - fun uniffi_xmtpv3_checksum_method_ffigroupmetadata_creator_inbox_id( + fun uniffi_xmtpv3_checksum_method_fficonversations_sync_all_conversations( ): Short fun uniffi_xmtpv3_checksum_method_ffigrouppermissions_policy_set( @@ -1865,18 +1919,27 @@ internal interface UniffiLib : Library { fun uniffi_xmtpv3_checksum_method_ffixmtpclient_add_wallet( ): Short + fun uniffi_xmtpv3_checksum_method_ffixmtpclient_addresses_from_inbox_id( + ): Short + fun uniffi_xmtpv3_checksum_method_ffixmtpclient_apply_signature_request( ): Short fun uniffi_xmtpv3_checksum_method_ffixmtpclient_can_message( ): Short + fun uniffi_xmtpv3_checksum_method_ffixmtpclient_conversation( + ): Short + fun uniffi_xmtpv3_checksum_method_ffixmtpclient_conversations( ): Short fun uniffi_xmtpv3_checksum_method_ffixmtpclient_db_reconnect( ): Short + fun uniffi_xmtpv3_checksum_method_ffixmtpclient_dm_conversation( + ): Short + fun uniffi_xmtpv3_checksum_method_ffixmtpclient_find_inbox_id( ): Short @@ -1886,9 +1949,6 @@ internal interface UniffiLib : Library { fun uniffi_xmtpv3_checksum_method_ffixmtpclient_get_latest_inbox_state( ): Short - fun uniffi_xmtpv3_checksum_method_ffixmtpclient_group( - ): Short - fun uniffi_xmtpv3_checksum_method_ffixmtpclient_inbox_id( ): Short @@ -2005,145 +2065,163 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_xmtpv3_checksum_func_verify_k256_sha256() != 25521.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_fficonversations_create_dm() != 61687.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_add_admin() != 52417.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_fficonversations_create_group() != 62996.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_add_members() != 3260.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_fficonversations_list() != 10804.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_add_members_by_inbox_id() != 28069.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_fficonversations_process_streamed_welcome_message() != 15283.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_add_super_admin() != 62984.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_fficonversations_stream() != 3079.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_added_by_inbox_id() != 12748.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_fficonversations_stream_all_messages() != 13204.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_admin_list() != 26668.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_fficonversations_sync() != 9054.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_consent_state() != 25033.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_created_at_ns() != 17973.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_find_messages() != 58508.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_group_description() != 53570.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_group_image_url_square() != 3200.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_group_metadata() != 21111.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_group_name() != 9344.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_fficonversations_sync_all_groups() != 3433.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_group_permissions() != 61947.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_add_admin() != 4600.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_group_pinned_frame_url() != 40964.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_add_members() != 27666.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_id() != 5542.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_add_members_by_inbox_id() != 23290.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_is_active() != 49581.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_add_super_admin() != 40681.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_is_admin() != 12325.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_added_by_inbox_id() != 37220.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_is_super_admin() != 25811.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_admin_list() != 51010.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_list_members() != 21260.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_consent_state() != 11630.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_process_streamed_conversation_message() != 1417.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_created_at_ns() != 4894.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_publish_messages() != 15643.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_find_messages() != 14930.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_remove_admin() != 7973.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_group_description() != 37045.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_remove_members() != 49452.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_group_image_url_square() != 16754.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_remove_members_by_inbox_id() != 53192.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_group_metadata() != 13139.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_remove_super_admin() != 46017.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_group_name() != 61525.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_send() != 7954.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_group_permissions() != 15980.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_send_optimistic() != 5885.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_group_pinned_frame_url() != 29388.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_stream() != 52815.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_id() != 36764.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_super_admin_list() != 50610.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_is_active() != 33848.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_sync() != 17206.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_is_admin() != 26672.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_update_consent_state() != 27721.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_is_super_admin() != 61614.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_update_group_description() != 14549.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_list_members() != 3945.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_update_group_image_url_square() != 36900.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_process_streamed_group_message() != 19069.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_update_group_name() != 62600.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_publish_messages() != 52808.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_update_group_pinned_frame_url() != 21997.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_remove_admin() != 57094.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversation_update_permission_policy() != 3743.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_remove_members() != 24336.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversationmetadata_conversation_type() != 48024.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_remove_members_by_inbox_id() != 45424.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversationmetadata_creator_inbox_id() != 61067.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_remove_super_admin() != 35336.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_create_dm() != 63785.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_send() != 37701.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_create_group() != 7282.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_send_optimistic() != 13872.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_list() != 42790.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_stream() != 34669.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_list_dms() != 41576.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_super_admin_list() != 5323.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_list_groups() != 2386.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_sync() != 24219.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_process_streamed_welcome_message() != 57376.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_update_consent_state() != 48124.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_stream() != 3079.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_update_group_description() != 34006.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_stream_all_dm_messages() != 37950.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_update_group_image_url_square() != 18878.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_stream_all_group_messages() != 50601.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_update_group_name() != 550.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_stream_all_messages() != 13204.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_update_group_pinned_frame_url() != 37434.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_stream_dms() != 4319.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroup_update_permission_policy() != 51936.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_stream_groups() != 10208.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroupmetadata_conversation_type() != 30827.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_sync() != 9054.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffigroupmetadata_creator_inbox_id() != 26872.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversations_sync_all_conversations() != 1140.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } if (lib.uniffi_xmtpv3_checksum_method_ffigrouppermissions_policy_set() != 24928.toShort()) { @@ -2203,18 +2281,27 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_add_wallet() != 23786.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_addresses_from_inbox_id() != 29264.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_apply_signature_request() != 32172.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_can_message() != 53502.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_conversation() != 60290.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_conversations() != 47463.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_db_reconnect() != 6707.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_dm_conversation() != 23917.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_find_inbox_id() != 59020.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -2224,9 +2311,6 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_get_latest_inbox_state() != 3165.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_group() != 64533.toShort()) { - throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") - } if (lib.uniffi_xmtpv3_checksum_method_ffixmtpclient_inbox_id() != 25128.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -2269,7 +2353,7 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_xmtpv3_checksum_method_ffilogger_log() != 56011.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_xmtpv3_checksum_method_fficonversationcallback_on_conversation() != 42.toShort()) { + if (lib.uniffi_xmtpv3_checksum_method_fficonversationcallback_on_conversation() != 25316.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } if (lib.uniffi_xmtpv3_checksum_method_ffimessagecallback_on_message() != 5286.toShort()) { @@ -2690,31 +2774,96 @@ private class JavaLangRefCleanable( override fun clean() = cleanable.clean() } -public interface FfiConversationsInterface { +public interface FfiConversationInterface { - suspend fun `createDm`(`accountAddress`: kotlin.String): FfiGroup + suspend fun `addAdmin`(`inboxId`: kotlin.String) - suspend fun `createGroup`( - `accountAddresses`: List, - `opts`: FfiCreateGroupOptions, - ): FfiGroup + suspend fun `addMembers`(`accountAddresses`: List) + + suspend fun `addMembersByInboxId`(`inboxIds`: List) - suspend fun `list`(`opts`: FfiListConversationsOptions): List + suspend fun `addSuperAdmin`(`inboxId`: kotlin.String) - suspend fun `processStreamedWelcomeMessage`(`envelopeBytes`: kotlin.ByteArray): FfiGroup + fun `addedByInboxId`(): kotlin.String - suspend fun `stream`(`callback`: FfiConversationCallback): FfiStreamCloser + fun `adminList`(): List - suspend fun `streamAllMessages`(`messageCallback`: FfiMessageCallback): FfiStreamCloser + fun `consentState`(): FfiConsentState + + fun `createdAtNs`(): kotlin.Long + + fun `findMessages`(`opts`: FfiListMessagesOptions): List + + fun `groupDescription`(): kotlin.String + + fun `groupImageUrlSquare`(): kotlin.String + + fun `groupMetadata`(): FfiConversationMetadata + + fun `groupName`(): kotlin.String + + fun `groupPermissions`(): FfiGroupPermissions + + fun `groupPinnedFrameUrl`(): kotlin.String + + fun `id`(): kotlin.ByteArray + + fun `isActive`(): kotlin.Boolean + + fun `isAdmin`(`inboxId`: kotlin.String): kotlin.Boolean + + fun `isSuperAdmin`(`inboxId`: kotlin.String): kotlin.Boolean + + suspend fun `listMembers`(): List + + suspend fun `processStreamedConversationMessage`(`envelopeBytes`: kotlin.ByteArray): FfiMessage + + /** + * Publish all unpublished messages + */ + suspend fun `publishMessages`() + + suspend fun `removeAdmin`(`inboxId`: kotlin.String) + + suspend fun `removeMembers`(`accountAddresses`: List) + + suspend fun `removeMembersByInboxId`(`inboxIds`: List) + + suspend fun `removeSuperAdmin`(`inboxId`: kotlin.String) + + suspend fun `send`(`contentBytes`: kotlin.ByteArray): kotlin.ByteArray + + /** + * send a message without immediately publishing to the delivery service. + */ + fun `sendOptimistic`(`contentBytes`: kotlin.ByteArray): kotlin.ByteArray + + suspend fun `stream`(`messageCallback`: FfiMessageCallback): FfiStreamCloser + + fun `superAdminList`(): List suspend fun `sync`() - suspend fun `syncAllGroups`(): kotlin.UInt + fun `updateConsentState`(`state`: FfiConsentState) + + suspend fun `updateGroupDescription`(`groupDescription`: kotlin.String) + + suspend fun `updateGroupImageUrlSquare`(`groupImageUrlSquare`: kotlin.String) + + suspend fun `updateGroupName`(`groupName`: kotlin.String) + + suspend fun `updateGroupPinnedFrameUrl`(`pinnedFrameUrl`: kotlin.String) + + suspend fun `updatePermissionPolicy`( + `permissionUpdateType`: FfiPermissionUpdateType, + `permissionPolicyOption`: FfiPermissionPolicy, + `metadataField`: FfiMetadataField?, + ) companion object } -open class FfiConversations : Disposable, AutoCloseable, FfiConversationsInterface { +open class FfiConversation : Disposable, AutoCloseable, FfiConversationInterface { constructor(pointer: Pointer) { this.pointer = pointer @@ -2783,7 +2932,7 @@ open class FfiConversations : Disposable, AutoCloseable, FfiConversationsInterfa override fun run() { pointer?.let { ptr -> uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_free_fficonversations(ptr, status) + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_free_fficonversation(ptr, status) } } } @@ -2791,37 +2940,38 @@ open class FfiConversations : Disposable, AutoCloseable, FfiConversationsInterfa fun uniffiClonePointer(): Pointer { return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_clone_fficonversations(pointer!!, status) + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_clone_fficonversation(pointer!!, status) } } @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `createDm`(`accountAddress`: kotlin.String): FfiGroup { + override suspend fun `addAdmin`(`inboxId`: kotlin.String) { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_create_dm( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_add_admin( thisPtr, - FfiConverterString.lower(`accountAddress`), + FfiConverterString.lower(`inboxId`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, // lift function - { FfiConverterTypeFfiGroup.lift(it) }, + { Unit }, + // Error FFI converter GenericException.ErrorHandler, ) @@ -2830,34 +2980,31 @@ open class FfiConversations : Disposable, AutoCloseable, FfiConversationsInterfa @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `createGroup`( - `accountAddresses`: List, - `opts`: FfiCreateGroupOptions, - ): FfiGroup { + override suspend fun `addMembers`(`accountAddresses`: List) { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_create_group( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_add_members( thisPtr, FfiConverterSequenceString.lower(`accountAddresses`), - FfiConverterTypeFfiCreateGroupOptions.lower(`opts`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, // lift function - { FfiConverterTypeFfiGroup.lift(it) }, + { Unit }, + // Error FFI converter GenericException.ErrorHandler, ) @@ -2866,30 +3013,31 @@ open class FfiConversations : Disposable, AutoCloseable, FfiConversationsInterfa @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `list`(`opts`: FfiListConversationsOptions): List { + override suspend fun `addMembersByInboxId`(`inboxIds`: List) { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_list( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_add_members_by_inbox_id( thisPtr, - FfiConverterTypeFfiListConversationsOptions.lower(`opts`), + FfiConverterSequenceString.lower(`inboxIds`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_rust_buffer( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_rust_buffer( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_rust_buffer(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, // lift function - { FfiConverterSequenceTypeFfiGroup.lift(it) }, + { Unit }, + // Error FFI converter GenericException.ErrorHandler, ) @@ -2898,470 +3046,656 @@ open class FfiConversations : Disposable, AutoCloseable, FfiConversationsInterfa @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `processStreamedWelcomeMessage`(`envelopeBytes`: kotlin.ByteArray): FfiGroup { + override suspend fun `addSuperAdmin`(`inboxId`: kotlin.String) { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_process_streamed_welcome_message( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_add_super_admin( thisPtr, - FfiConverterByteArray.lower(`envelopeBytes`), + FfiConverterString.lower(`inboxId`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, // lift function - { FfiConverterTypeFfiGroup.lift(it) }, + { Unit }, + // Error FFI converter GenericException.ErrorHandler, ) } - @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `stream`(`callback`: FfiConversationCallback): FfiStreamCloser { - return uniffiRustCallAsync( - callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_stream( - thisPtr, - FfiConverterTypeFfiConversationCallback.lower(`callback`), - ) - }, - { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( - future, - callback, - continuation - ) - }, - { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( - future, - continuation - ) - }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, - // lift function - { FfiConverterTypeFfiStreamCloser.lift(it) }, - // Error FFI converter - UniffiNullRustCallStatusErrorHandler, + @Throws(GenericException::class) + override fun `addedByInboxId`(): kotlin.String { + return FfiConverterString.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_added_by_inbox_id( + it, _status + ) + } + } ) } - @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `streamAllMessages`(`messageCallback`: FfiMessageCallback): FfiStreamCloser { - return uniffiRustCallAsync( - callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_stream_all_messages( - thisPtr, - FfiConverterTypeFfiMessageCallback.lower(`messageCallback`), - ) - }, - { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( - future, - callback, - continuation - ) - }, - { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( - future, - continuation - ) - }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, - // lift function - { FfiConverterTypeFfiStreamCloser.lift(it) }, - // Error FFI converter - UniffiNullRustCallStatusErrorHandler, + @Throws(GenericException::class) + override fun `adminList`(): List { + return FfiConverterSequenceString.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_admin_list( + it, _status + ) + } + } ) } @Throws(GenericException::class) - @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `sync`() { - return uniffiRustCallAsync( - callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_sync( - thisPtr, - + override fun `consentState`(): FfiConsentState { + return FfiConverterTypeFfiConsentState.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_consent_state( + it, _status ) - }, - { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( - future, - callback, - continuation - ) - }, - { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( - future, - continuation - ) - }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, - // lift function - { Unit }, + } + } + ) + } - // Error FFI converter - GenericException.ErrorHandler, + + override fun `createdAtNs`(): kotlin.Long { + return FfiConverterLong.lift( + callWithPointer { + uniffiRustCall() { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_created_at_ns( + it, _status + ) + } + } ) } @Throws(GenericException::class) - @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `syncAllGroups`(): kotlin.UInt { - return uniffiRustCallAsync( - callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_sync_all_groups( - thisPtr, - + override fun `findMessages`(`opts`: FfiListMessagesOptions): List { + return FfiConverterSequenceTypeFfiMessage.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_find_messages( + it, FfiConverterTypeFfiListMessagesOptions.lower(`opts`), _status ) - }, - { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_u32( - future, - callback, - continuation - ) - }, - { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_u32( - future, - continuation - ) - }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_u32(future) }, - // lift function - { FfiConverterUInt.lift(it) }, - // Error FFI converter - GenericException.ErrorHandler, + } + } ) } - companion object - -} + @Throws(GenericException::class) + override fun `groupDescription`(): kotlin.String { + return FfiConverterString.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_group_description( + it, _status + ) + } + } + ) + } -public object FfiConverterTypeFfiConversations : FfiConverter { - override fun lower(value: FfiConversations): Pointer { - return value.uniffiClonePointer() + @Throws(GenericException::class) + override fun `groupImageUrlSquare`(): kotlin.String { + return FfiConverterString.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_group_image_url_square( + it, _status + ) + } + } + ) } - override fun lift(value: Pointer): FfiConversations { - return FfiConversations(value) - } - override fun read(buf: ByteBuffer): FfiConversations { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) + @Throws(GenericException::class) + override fun `groupMetadata`(): FfiConversationMetadata { + return FfiConverterTypeFfiConversationMetadata.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_group_metadata( + it, _status + ) + } + } + ) } - override fun allocationSize(value: FfiConversations) = 8UL - override fun write(value: FfiConversations, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) + @Throws(GenericException::class) + override fun `groupName`(): kotlin.String { + return FfiConverterString.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_group_name( + it, _status + ) + } + } + ) } -} -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// + @Throws(GenericException::class) + override fun `groupPermissions`(): FfiGroupPermissions { + return FfiConverterTypeFfiGroupPermissions.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_group_permissions( + it, _status + ) + } + } + ) + } -public interface FfiGroupInterface { + @Throws(GenericException::class) + override fun `groupPinnedFrameUrl`(): kotlin.String { + return FfiConverterString.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_group_pinned_frame_url( + it, _status + ) + } + } + ) + } - suspend fun `addAdmin`(`inboxId`: kotlin.String) - suspend fun `addMembers`(`accountAddresses`: List) + override fun `id`(): kotlin.ByteArray { + return FfiConverterByteArray.lift( + callWithPointer { + uniffiRustCall() { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_id( + it, _status + ) + } + } + ) + } - suspend fun `addMembersByInboxId`(`inboxIds`: List) - suspend fun `addSuperAdmin`(`inboxId`: kotlin.String) + @Throws(GenericException::class) + override fun `isActive`(): kotlin.Boolean { + return FfiConverterBoolean.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_is_active( + it, _status + ) + } + } + ) + } - fun `addedByInboxId`(): kotlin.String - fun `adminList`(): List + @Throws(GenericException::class) + override fun `isAdmin`(`inboxId`: kotlin.String): kotlin.Boolean { + return FfiConverterBoolean.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_is_admin( + it, FfiConverterString.lower(`inboxId`), _status + ) + } + } + ) + } - fun `consentState`(): FfiConsentState - fun `createdAtNs`(): kotlin.Long + @Throws(GenericException::class) + override fun `isSuperAdmin`(`inboxId`: kotlin.String): kotlin.Boolean { + return FfiConverterBoolean.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_is_super_admin( + it, FfiConverterString.lower(`inboxId`), _status + ) + } + } + ) + } - fun `findMessages`(`opts`: FfiListMessagesOptions): List - fun `groupDescription`(): kotlin.String + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `listMembers`(): List { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_list_members( + thisPtr, - fun `groupImageUrlSquare`(): kotlin.String + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_rust_buffer( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_rust_buffer( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_rust_buffer(future) }, + // lift function + { FfiConverterSequenceTypeFfiConversationMember.lift(it) }, + // Error FFI converter + GenericException.ErrorHandler, + ) + } - fun `groupMetadata`(): FfiGroupMetadata - fun `groupName`(): kotlin.String + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `processStreamedConversationMessage`(`envelopeBytes`: kotlin.ByteArray): FfiMessage { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_process_streamed_conversation_message( + thisPtr, + FfiConverterByteArray.lower(`envelopeBytes`), + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_rust_buffer( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_rust_buffer( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_rust_buffer(future) }, + // lift function + { FfiConverterTypeFfiMessage.lift(it) }, + // Error FFI converter + GenericException.ErrorHandler, + ) + } - fun `groupPermissions`(): FfiGroupPermissions - fun `groupPinnedFrameUrl`(): kotlin.String + /** + * Publish all unpublished messages + */ + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `publishMessages`() { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_publish_messages( + thisPtr, - fun `id`(): kotlin.ByteArray + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + // lift function + { Unit }, - fun `isActive`(): kotlin.Boolean + // Error FFI converter + GenericException.ErrorHandler, + ) + } - fun `isAdmin`(`inboxId`: kotlin.String): kotlin.Boolean - fun `isSuperAdmin`(`inboxId`: kotlin.String): kotlin.Boolean + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `removeAdmin`(`inboxId`: kotlin.String) { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_remove_admin( + thisPtr, + FfiConverterString.lower(`inboxId`), + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + // lift function + { Unit }, - suspend fun `listMembers`(): List + // Error FFI converter + GenericException.ErrorHandler, + ) + } - suspend fun `processStreamedGroupMessage`(`envelopeBytes`: kotlin.ByteArray): FfiMessage - /** - * Publish all unpublished messages - */ - suspend fun `publishMessages`() + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `removeMembers`(`accountAddresses`: List) { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_remove_members( + thisPtr, + FfiConverterSequenceString.lower(`accountAddresses`), + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + // lift function + { Unit }, - suspend fun `removeAdmin`(`inboxId`: kotlin.String) + // Error FFI converter + GenericException.ErrorHandler, + ) + } + + + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `removeMembersByInboxId`(`inboxIds`: List) { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_remove_members_by_inbox_id( + thisPtr, + FfiConverterSequenceString.lower(`inboxIds`), + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + // lift function + { Unit }, + + // Error FFI converter + GenericException.ErrorHandler, + ) + } + + + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `removeSuperAdmin`(`inboxId`: kotlin.String) { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_remove_super_admin( + thisPtr, + FfiConverterString.lower(`inboxId`), + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + // lift function + { Unit }, - suspend fun `removeMembers`(`accountAddresses`: List) + // Error FFI converter + GenericException.ErrorHandler, + ) + } - suspend fun `removeMembersByInboxId`(`inboxIds`: List) - suspend fun `removeSuperAdmin`(`inboxId`: kotlin.String) + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `send`(`contentBytes`: kotlin.ByteArray): kotlin.ByteArray { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_send( + thisPtr, + FfiConverterByteArray.lower(`contentBytes`), + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_rust_buffer( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_rust_buffer( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_rust_buffer(future) }, + // lift function + { FfiConverterByteArray.lift(it) }, + // Error FFI converter + GenericException.ErrorHandler, + ) + } - suspend fun `send`(`contentBytes`: kotlin.ByteArray): kotlin.ByteArray /** * send a message without immediately publishing to the delivery service. */ - fun `sendOptimistic`(`contentBytes`: kotlin.ByteArray): kotlin.ByteArray - - suspend fun `stream`(`messageCallback`: FfiMessageCallback): FfiStreamCloser - - fun `superAdminList`(): List - - suspend fun `sync`() - - fun `updateConsentState`(`state`: FfiConsentState) - - suspend fun `updateGroupDescription`(`groupDescription`: kotlin.String) - - suspend fun `updateGroupImageUrlSquare`(`groupImageUrlSquare`: kotlin.String) - - suspend fun `updateGroupName`(`groupName`: kotlin.String) - - suspend fun `updateGroupPinnedFrameUrl`(`pinnedFrameUrl`: kotlin.String) + @Throws(GenericException::class) + override fun `sendOptimistic`(`contentBytes`: kotlin.ByteArray): kotlin.ByteArray { + return FfiConverterByteArray.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_send_optimistic( + it, FfiConverterByteArray.lower(`contentBytes`), _status + ) + } + } + ) + } - suspend fun `updatePermissionPolicy`( - `permissionUpdateType`: FfiPermissionUpdateType, - `permissionPolicyOption`: FfiPermissionPolicy, - `metadataField`: FfiMetadataField?, - ) - companion object -} + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `stream`(`messageCallback`: FfiMessageCallback): FfiStreamCloser { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_stream( + thisPtr, + FfiConverterTypeFfiMessageCallback.lower(`messageCallback`), + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, + // lift function + { FfiConverterTypeFfiStreamCloser.lift(it) }, + // Error FFI converter + UniffiNullRustCallStatusErrorHandler, + ) + } -open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) + @Throws(GenericException::class) + override fun `superAdminList`(): List { + return FfiConverterSequenceString.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_super_admin_list( + it, _status + ) + } + } + ) } - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `sync`() { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_sync( + thisPtr, - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + // lift function + { Unit }, - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } + // Error FFI converter + GenericException.ErrorHandler, + ) } - @Synchronized - override fun close() { - this.destroy() - } - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (!this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() + @Throws(GenericException::class) + override fun `updateConsentState`(`state`: FfiConsentState) = + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_update_consent_state( + it, FfiConverterTypeFfiConsentState.lower(`state`), _status + ) } } - } - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_free_ffigroup(ptr, status) - } - } - } - } - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_clone_ffigroup(pointer!!, status) - } + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `updateGroupDescription`(`groupDescription`: kotlin.String) { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_update_group_description( + thisPtr, + FfiConverterString.lower(`groupDescription`), + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + // lift function + { Unit }, + + // Error FFI converter + GenericException.ErrorHandler, + ) } @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `addAdmin`(`inboxId`: kotlin.String) { + override suspend fun `updateGroupImageUrlSquare`(`groupImageUrlSquare`: kotlin.String) { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_add_admin( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_update_group_image_url_square( thisPtr, - FfiConverterString.lower(`inboxId`), + FfiConverterString.lower(`groupImageUrlSquare`), ) }, { future, callback, continuation -> @@ -3389,12 +3723,12 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `addMembers`(`accountAddresses`: List) { + override suspend fun `updateGroupName`(`groupName`: kotlin.String) { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_add_members( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_update_group_name( thisPtr, - FfiConverterSequenceString.lower(`accountAddresses`), + FfiConverterString.lower(`groupName`), ) }, { future, callback, continuation -> @@ -3422,12 +3756,12 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `addMembersByInboxId`(`inboxIds`: List) { + override suspend fun `updateGroupPinnedFrameUrl`(`pinnedFrameUrl`: kotlin.String) { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_add_members_by_inbox_id( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_update_group_pinned_frame_url( thisPtr, - FfiConverterSequenceString.lower(`inboxIds`), + FfiConverterString.lower(`pinnedFrameUrl`), ) }, { future, callback, continuation -> @@ -3455,12 +3789,18 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `addSuperAdmin`(`inboxId`: kotlin.String) { + override suspend fun `updatePermissionPolicy`( + `permissionUpdateType`: FfiPermissionUpdateType, + `permissionPolicyOption`: FfiPermissionPolicy, + `metadataField`: FfiMetadataField?, + ) { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_add_super_admin( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversation_update_permission_policy( thisPtr, - FfiConverterString.lower(`inboxId`), + FfiConverterTypeFfiPermissionUpdateType.lower(`permissionUpdateType`), + FfiConverterTypeFfiPermissionPolicy.lower(`permissionPolicyOption`), + FfiConverterOptionalTypeFfiMetadataField.lower(`metadataField`), ) }, { future, callback, continuation -> @@ -3486,151 +3826,229 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { } - @Throws(GenericException::class) - override fun `addedByInboxId`(): kotlin.String { - return FfiConverterString.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_added_by_inbox_id( - it, _status - ) - } - } - ) - } + companion object +} - @Throws(GenericException::class) - override fun `adminList`(): List { - return FfiConverterSequenceString.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_admin_list( - it, _status - ) - } - } - ) +public object FfiConverterTypeFfiConversation : FfiConverter { + + override fun lower(value: FfiConversation): Pointer { + return value.uniffiClonePointer() } + override fun lift(value: Pointer): FfiConversation { + return FfiConversation(value) + } - @Throws(GenericException::class) - override fun `consentState`(): FfiConsentState { - return FfiConverterTypeFfiConsentState.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_consent_state( - it, _status - ) - } - } - ) + override fun read(buf: ByteBuffer): FfiConversation { + // The Rust code always writes pointers as 8 bytes, and will + // fail to compile if they don't fit. + return lift(Pointer(buf.getLong())) } + override fun allocationSize(value: FfiConversation) = 8UL - override fun `createdAtNs`(): kotlin.Long { - return FfiConverterLong.lift( - callWithPointer { - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_created_at_ns( - it, _status - ) - } - } - ) + override fun write(value: FfiConversation, buf: ByteBuffer) { + // The Rust code always expects pointers written as 8 bytes, + // and will fail to compile if they don't fit. + buf.putLong(Pointer.nativeValue(lower(value))) } +} - @Throws(GenericException::class) - override fun `findMessages`(`opts`: FfiListMessagesOptions): List { - return FfiConverterSequenceTypeFfiMessage.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_find_messages( - it, FfiConverterTypeFfiListMessagesOptions.lower(`opts`), _status - ) - } - } - ) - } +// This template implements a class for working with a Rust struct via a Pointer/Arc +// to the live Rust struct on the other side of the FFI. +// +// Each instance implements core operations for working with the Rust `Arc` and the +// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. +// +// There's some subtlety here, because we have to be careful not to operate on a Rust +// struct after it has been dropped, and because we must expose a public API for freeing +// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: +// +// * Each instance holds an opaque pointer to the underlying Rust struct. +// Method calls need to read this pointer from the object's state and pass it in to +// the Rust FFI. +// +// * When an instance is no longer needed, its pointer should be passed to a +// special destructor function provided by the Rust FFI, which will drop the +// underlying Rust struct. +// +// * Given an instance, calling code is expected to call the special +// `destroy` method in order to free it after use, either by calling it explicitly +// or by using a higher-level helper like the `use` method. Failing to do so risks +// leaking the underlying Rust struct. +// +// * We can't assume that calling code will do the right thing, and must be prepared +// to handle Kotlin method calls executing concurrently with or even after a call to +// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. +// +// * We must never allow Rust code to operate on the underlying Rust struct after +// the destructor has been called, and must never call the destructor more than once. +// Doing so may trigger memory unsafety. +// +// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` +// is implemented to call the destructor when the Kotlin object becomes unreachable. +// This is done in a background thread. This is not a panacea, and client code should be aware that +// 1. the thread may starve if some there are objects that have poorly performing +// `drop` methods or do significant work in their `drop` methods. +// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, +// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). +// +// If we try to implement this with mutual exclusion on access to the pointer, there is the +// possibility of a race between a method call and a concurrent call to `destroy`: +// +// * Thread A starts a method call, reads the value of the pointer, but is interrupted +// before it can pass the pointer over the FFI to Rust. +// * Thread B calls `destroy` and frees the underlying Rust struct. +// * Thread A resumes, passing the already-read pointer value to Rust and triggering +// a use-after-free. +// +// One possible solution would be to use a `ReadWriteLock`, with each method call taking +// a read lock (and thus allowed to run concurrently) and the special `destroy` method +// taking a write lock (and thus blocking on live method calls). However, we aim not to +// generate methods with any hidden blocking semantics, and a `destroy` method that might +// block if called incorrectly seems to meet that bar. +// +// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track +// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` +// has been called. These are updated according to the following rules: +// +// * The initial value of the counter is 1, indicating a live object with no in-flight calls. +// The initial value for the flag is false. +// +// * At the start of each method call, we atomically check the counter. +// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. +// If it is nonzero them we atomically increment it by 1 and proceed with the method call. +// +// * At the end of each method call, we atomically decrement and check the counter. +// If it has reached zero then we destroy the underlying Rust struct. +// +// * When `destroy` is called, we atomically flip the flag from false to true. +// If the flag was already true we silently fail. +// Otherwise we atomically decrement and check the counter. +// If it has reached zero then we destroy the underlying Rust struct. +// +// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, +// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. +// +// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been +// called *and* all in-flight method calls have completed, avoiding violating any of the expectations +// of the underlying Rust code. +// +// This makes a cleaner a better alternative to _not_ calling `destroy()` as +// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` +// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner +// thread may be starved, and the app will leak memory. +// +// In this case, `destroy`ing manually may be a better solution. +// +// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects +// with Rust peers are reclaimed: +// +// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: +// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: +// 3. The memory is reclaimed when the process terminates. +// +// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 +// - @Throws(GenericException::class) - override fun `groupDescription`(): kotlin.String { - return FfiConverterString.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_group_description( - it, _status - ) - } - } - ) - } +public interface FfiConversationMetadataInterface { + fun `conversationType`(): kotlin.String - @Throws(GenericException::class) - override fun `groupImageUrlSquare`(): kotlin.String { - return FfiConverterString.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_group_image_url_square( - it, _status - ) - } - } - ) + fun `creatorInboxId`(): kotlin.String + + companion object +} + +open class FfiConversationMetadata : Disposable, AutoCloseable, FfiConversationMetadataInterface { + + constructor(pointer: Pointer) { + this.pointer = pointer + this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) + } + + /** + * This constructor can be used to instantiate a fake object. Only used for tests. Any + * attempt to actually use an object constructed this way will fail as there is no + * connected Rust object. + */ + @Suppress("UNUSED_PARAMETER") + constructor(noPointer: NoPointer) { + this.pointer = null + this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) } + protected val pointer: Pointer? + protected val cleanable: UniffiCleaner.Cleanable - @Throws(GenericException::class) - override fun `groupMetadata`(): FfiGroupMetadata { - return FfiConverterTypeFfiGroupMetadata.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_group_metadata( - it, _status - ) - } + private val wasDestroyed = AtomicBoolean(false) + private val callCounter = AtomicLong(1) + + override fun destroy() { + // Only allow a single call to this method. + // TODO: maybe we should log a warning if called more than once? + if (this.wasDestroyed.compareAndSet(false, true)) { + // This decrement always matches the initial count of 1 given at creation time. + if (this.callCounter.decrementAndGet() == 0L) { + cleanable.clean() } - ) + } } + @Synchronized + override fun close() { + this.destroy() + } - @Throws(GenericException::class) - override fun `groupName`(): kotlin.String { - return FfiConverterString.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_group_name( - it, _status - ) - } + internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { + // Check and increment the call counter, to keep the object alive. + // This needs a compare-and-set retry loop in case of concurrent updates. + do { + val c = this.callCounter.get() + if (c == 0L) { + throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") + } + if (c == Long.MAX_VALUE) { + throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") } - ) + } while (!this.callCounter.compareAndSet(c, c + 1L)) + // Now we can safely do the method call without the pointer being freed concurrently. + try { + return block(this.uniffiClonePointer()) + } finally { + // This decrement always matches the increment we performed above. + if (this.callCounter.decrementAndGet() == 0L) { + cleanable.clean() + } + } } - - @Throws(GenericException::class) - override fun `groupPermissions`(): FfiGroupPermissions { - return FfiConverterTypeFfiGroupPermissions.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_group_permissions( - it, _status - ) + // Use a static inner class instead of a closure so as not to accidentally + // capture `this` as part of the cleanable's action. + private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { + override fun run() { + pointer?.let { ptr -> + uniffiRustCall { status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_free_fficonversationmetadata(ptr, status) } } - ) + } } + fun uniffiClonePointer(): Pointer { + return uniffiRustCall() { status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_clone_fficonversationmetadata(pointer!!, status) + } + } - @Throws(GenericException::class) - override fun `groupPinnedFrameUrl`(): kotlin.String { + override fun `conversationType`(): kotlin.String { return FfiConverterString.lift( callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_group_pinned_frame_url( + uniffiRustCall() { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversationmetadata_conversation_type( it, _status ) } @@ -3639,11 +4057,11 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { } - override fun `id`(): kotlin.ByteArray { - return FfiConverterByteArray.lift( + override fun `creatorInboxId`(): kotlin.String { + return FfiConverterString.lift( callWithPointer { uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_id( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversationmetadata_creator_inbox_id( it, _status ) } @@ -3652,175 +4070,279 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { } - @Throws(GenericException::class) - override fun `isActive`(): kotlin.Boolean { - return FfiConverterBoolean.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_is_active( - it, _status - ) - } - } - ) + companion object + +} + +public object FfiConverterTypeFfiConversationMetadata : + FfiConverter { + + override fun lower(value: FfiConversationMetadata): Pointer { + return value.uniffiClonePointer() } + override fun lift(value: Pointer): FfiConversationMetadata { + return FfiConversationMetadata(value) + } - @Throws(GenericException::class) - override fun `isAdmin`(`inboxId`: kotlin.String): kotlin.Boolean { - return FfiConverterBoolean.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_is_admin( - it, FfiConverterString.lower(`inboxId`), _status - ) - } - } - ) + override fun read(buf: ByteBuffer): FfiConversationMetadata { + // The Rust code always writes pointers as 8 bytes, and will + // fail to compile if they don't fit. + return lift(Pointer(buf.getLong())) } + override fun allocationSize(value: FfiConversationMetadata) = 8UL - @Throws(GenericException::class) - override fun `isSuperAdmin`(`inboxId`: kotlin.String): kotlin.Boolean { - return FfiConverterBoolean.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_is_super_admin( - it, FfiConverterString.lower(`inboxId`), _status - ) - } - } - ) + override fun write(value: FfiConversationMetadata, buf: ByteBuffer) { + // The Rust code always expects pointers written as 8 bytes, + // and will fail to compile if they don't fit. + buf.putLong(Pointer.nativeValue(lower(value))) } +} - @Throws(GenericException::class) - @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `listMembers`(): List { - return uniffiRustCallAsync( - callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_list_members( - thisPtr, +// This template implements a class for working with a Rust struct via a Pointer/Arc +// to the live Rust struct on the other side of the FFI. +// +// Each instance implements core operations for working with the Rust `Arc` and the +// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. +// +// There's some subtlety here, because we have to be careful not to operate on a Rust +// struct after it has been dropped, and because we must expose a public API for freeing +// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: +// +// * Each instance holds an opaque pointer to the underlying Rust struct. +// Method calls need to read this pointer from the object's state and pass it in to +// the Rust FFI. +// +// * When an instance is no longer needed, its pointer should be passed to a +// special destructor function provided by the Rust FFI, which will drop the +// underlying Rust struct. +// +// * Given an instance, calling code is expected to call the special +// `destroy` method in order to free it after use, either by calling it explicitly +// or by using a higher-level helper like the `use` method. Failing to do so risks +// leaking the underlying Rust struct. +// +// * We can't assume that calling code will do the right thing, and must be prepared +// to handle Kotlin method calls executing concurrently with or even after a call to +// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. +// +// * We must never allow Rust code to operate on the underlying Rust struct after +// the destructor has been called, and must never call the destructor more than once. +// Doing so may trigger memory unsafety. +// +// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` +// is implemented to call the destructor when the Kotlin object becomes unreachable. +// This is done in a background thread. This is not a panacea, and client code should be aware that +// 1. the thread may starve if some there are objects that have poorly performing +// `drop` methods or do significant work in their `drop` methods. +// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, +// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). +// +// If we try to implement this with mutual exclusion on access to the pointer, there is the +// possibility of a race between a method call and a concurrent call to `destroy`: +// +// * Thread A starts a method call, reads the value of the pointer, but is interrupted +// before it can pass the pointer over the FFI to Rust. +// * Thread B calls `destroy` and frees the underlying Rust struct. +// * Thread A resumes, passing the already-read pointer value to Rust and triggering +// a use-after-free. +// +// One possible solution would be to use a `ReadWriteLock`, with each method call taking +// a read lock (and thus allowed to run concurrently) and the special `destroy` method +// taking a write lock (and thus blocking on live method calls). However, we aim not to +// generate methods with any hidden blocking semantics, and a `destroy` method that might +// block if called incorrectly seems to meet that bar. +// +// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track +// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` +// has been called. These are updated according to the following rules: +// +// * The initial value of the counter is 1, indicating a live object with no in-flight calls. +// The initial value for the flag is false. +// +// * At the start of each method call, we atomically check the counter. +// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. +// If it is nonzero them we atomically increment it by 1 and proceed with the method call. +// +// * At the end of each method call, we atomically decrement and check the counter. +// If it has reached zero then we destroy the underlying Rust struct. +// +// * When `destroy` is called, we atomically flip the flag from false to true. +// If the flag was already true we silently fail. +// Otherwise we atomically decrement and check the counter. +// If it has reached zero then we destroy the underlying Rust struct. +// +// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, +// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. +// +// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been +// called *and* all in-flight method calls have completed, avoiding violating any of the expectations +// of the underlying Rust code. +// +// This makes a cleaner a better alternative to _not_ calling `destroy()` as +// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` +// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner +// thread may be starved, and the app will leak memory. +// +// In this case, `destroy`ing manually may be a better solution. +// +// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects +// with Rust peers are reclaimed: +// +// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: +// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: +// 3. The memory is reclaimed when the process terminates. +// +// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 +// - ) - }, - { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_rust_buffer( - future, - callback, - continuation - ) - }, - { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_rust_buffer( - future, - continuation - ) - }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_rust_buffer(future) }, - // lift function - { FfiConverterSequenceTypeFfiGroupMember.lift(it) }, - // Error FFI converter - GenericException.ErrorHandler, - ) - } +public interface FfiConversationsInterface { - @Throws(GenericException::class) - @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `processStreamedGroupMessage`(`envelopeBytes`: kotlin.ByteArray): FfiMessage { - return uniffiRustCallAsync( - callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_process_streamed_group_message( - thisPtr, - FfiConverterByteArray.lower(`envelopeBytes`), - ) - }, - { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_rust_buffer( - future, - callback, - continuation - ) - }, - { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_rust_buffer( - future, - continuation - ) - }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_rust_buffer(future) }, - // lift function - { FfiConverterTypeFfiMessage.lift(it) }, - // Error FFI converter - GenericException.ErrorHandler, - ) - } + suspend fun `createDm`(`accountAddress`: kotlin.String): FfiConversation + + suspend fun `createGroup`( + `accountAddresses`: List, + `opts`: FfiCreateGroupOptions, + ): FfiConversation + + suspend fun `list`(`opts`: FfiListConversationsOptions): List + + suspend fun `listDms`(`opts`: FfiListConversationsOptions): List + + suspend fun `listGroups`(`opts`: FfiListConversationsOptions): List + + suspend fun `processStreamedWelcomeMessage`(`envelopeBytes`: kotlin.ByteArray): FfiConversation + + suspend fun `stream`(`callback`: FfiConversationCallback): FfiStreamCloser + + suspend fun `streamAllDmMessages`(`messageCallback`: FfiMessageCallback): FfiStreamCloser + + suspend fun `streamAllGroupMessages`(`messageCallback`: FfiMessageCallback): FfiStreamCloser + + suspend fun `streamAllMessages`(`messageCallback`: FfiMessageCallback): FfiStreamCloser + + suspend fun `streamDms`(`callback`: FfiConversationCallback): FfiStreamCloser + + suspend fun `streamGroups`(`callback`: FfiConversationCallback): FfiStreamCloser + + suspend fun `sync`() + + suspend fun `syncAllConversations`(): kotlin.UInt + + companion object +} + +open class FfiConversations : Disposable, AutoCloseable, FfiConversationsInterface { + constructor(pointer: Pointer) { + this.pointer = pointer + this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) + } /** - * Publish all unpublished messages + * This constructor can be used to instantiate a fake object. Only used for tests. Any + * attempt to actually use an object constructed this way will fail as there is no + * connected Rust object. */ - @Throws(GenericException::class) - @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `publishMessages`() { - return uniffiRustCallAsync( - callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_publish_messages( - thisPtr, + @Suppress("UNUSED_PARAMETER") + constructor(noPointer: NoPointer) { + this.pointer = null + this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) + } - ) - }, - { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( - future, - callback, - continuation - ) - }, - { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( - future, - continuation - ) - }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, - // lift function - { Unit }, + protected val pointer: Pointer? + protected val cleanable: UniffiCleaner.Cleanable - // Error FFI converter - GenericException.ErrorHandler, - ) + private val wasDestroyed = AtomicBoolean(false) + private val callCounter = AtomicLong(1) + + override fun destroy() { + // Only allow a single call to this method. + // TODO: maybe we should log a warning if called more than once? + if (this.wasDestroyed.compareAndSet(false, true)) { + // This decrement always matches the initial count of 1 given at creation time. + if (this.callCounter.decrementAndGet() == 0L) { + cleanable.clean() + } + } + } + + @Synchronized + override fun close() { + this.destroy() + } + + internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { + // Check and increment the call counter, to keep the object alive. + // This needs a compare-and-set retry loop in case of concurrent updates. + do { + val c = this.callCounter.get() + if (c == 0L) { + throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") + } + if (c == Long.MAX_VALUE) { + throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") + } + } while (!this.callCounter.compareAndSet(c, c + 1L)) + // Now we can safely do the method call without the pointer being freed concurrently. + try { + return block(this.uniffiClonePointer()) + } finally { + // This decrement always matches the increment we performed above. + if (this.callCounter.decrementAndGet() == 0L) { + cleanable.clean() + } + } + } + + // Use a static inner class instead of a closure so as not to accidentally + // capture `this` as part of the cleanable's action. + private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { + override fun run() { + pointer?.let { ptr -> + uniffiRustCall { status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_free_fficonversations(ptr, status) + } + } + } + } + + fun uniffiClonePointer(): Pointer { + return uniffiRustCall() { status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_clone_fficonversations(pointer!!, status) + } } @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `removeAdmin`(`inboxId`: kotlin.String) { + override suspend fun `createDm`(`accountAddress`: kotlin.String): FfiConversation { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_remove_admin( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_create_dm( thisPtr, - FfiConverterString.lower(`inboxId`), + FfiConverterString.lower(`accountAddress`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, // lift function - { Unit }, - + { FfiConverterTypeFfiConversation.lift(it) }, // Error FFI converter GenericException.ErrorHandler, ) @@ -3829,31 +4351,34 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `removeMembers`(`accountAddresses`: List) { + override suspend fun `createGroup`( + `accountAddresses`: List, + `opts`: FfiCreateGroupOptions, + ): FfiConversation { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_remove_members( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_create_group( thisPtr, FfiConverterSequenceString.lower(`accountAddresses`), + FfiConverterTypeFfiCreateGroupOptions.lower(`opts`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, // lift function - { Unit }, - + { FfiConverterTypeFfiConversation.lift(it) }, // Error FFI converter GenericException.ErrorHandler, ) @@ -3862,31 +4387,30 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `removeMembersByInboxId`(`inboxIds`: List) { + override suspend fun `list`(`opts`: FfiListConversationsOptions): List { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_remove_members_by_inbox_id( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_list( thisPtr, - FfiConverterSequenceString.lower(`inboxIds`), + FfiConverterTypeFfiListConversationsOptions.lower(`opts`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_rust_buffer( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_rust_buffer( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_rust_buffer(future) }, // lift function - { Unit }, - + { FfiConverterSequenceTypeFfiConversation.lift(it) }, // Error FFI converter GenericException.ErrorHandler, ) @@ -3895,31 +4419,30 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `removeSuperAdmin`(`inboxId`: kotlin.String) { + override suspend fun `listDms`(`opts`: FfiListConversationsOptions): List { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_remove_super_admin( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_list_dms( thisPtr, - FfiConverterString.lower(`inboxId`), + FfiConverterTypeFfiListConversationsOptions.lower(`opts`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_rust_buffer( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_rust_buffer( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_rust_buffer(future) }, // lift function - { Unit }, - + { FfiConverterSequenceTypeFfiConversation.lift(it) }, // Error FFI converter GenericException.ErrorHandler, ) @@ -3928,12 +4451,12 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `send`(`contentBytes`: kotlin.ByteArray): kotlin.ByteArray { + override suspend fun `listGroups`(`opts`: FfiListConversationsOptions): List { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_send( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_list_groups( thisPtr, - FfiConverterByteArray.lower(`contentBytes`), + FfiConverterTypeFfiListConversationsOptions.lower(`opts`), ) }, { future, callback, continuation -> @@ -3951,37 +4474,21 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { }, { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_rust_buffer(future) }, // lift function - { FfiConverterByteArray.lift(it) }, + { FfiConverterSequenceTypeFfiConversation.lift(it) }, // Error FFI converter GenericException.ErrorHandler, ) } - /** - * send a message without immediately publishing to the delivery service. - */ @Throws(GenericException::class) - override fun `sendOptimistic`(`contentBytes`: kotlin.ByteArray): kotlin.ByteArray { - return FfiConverterByteArray.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_send_optimistic( - it, FfiConverterByteArray.lower(`contentBytes`), _status - ) - } - } - ) - } - - @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `stream`(`messageCallback`: FfiMessageCallback): FfiStreamCloser { + override suspend fun `processStreamedWelcomeMessage`(`envelopeBytes`: kotlin.ByteArray): FfiConversation { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_stream( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_process_streamed_welcome_message( thisPtr, - FfiConverterTypeFfiMessageCallback.lower(`messageCallback`), + FfiConverterByteArray.lower(`envelopeBytes`), ) }, { future, callback, continuation -> @@ -3999,482 +4506,260 @@ open class FfiGroup : Disposable, AutoCloseable, FfiGroupInterface { }, { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, // lift function - { FfiConverterTypeFfiStreamCloser.lift(it) }, + { FfiConverterTypeFfiConversation.lift(it) }, // Error FFI converter - UniffiNullRustCallStatusErrorHandler, - ) - } - - - @Throws(GenericException::class) - override fun `superAdminList`(): List { - return FfiConverterSequenceString.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_super_admin_list( - it, _status - ) - } - } + GenericException.ErrorHandler, ) } - @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `sync`() { + override suspend fun `stream`(`callback`: FfiConversationCallback): FfiStreamCloser { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_sync( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_stream( thisPtr, - - ) + FfiConverterTypeFfiConversationCallback.lower(`callback`), + ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, // lift function - { Unit }, - + { FfiConverterTypeFfiStreamCloser.lift(it) }, // Error FFI converter - GenericException.ErrorHandler, + UniffiNullRustCallStatusErrorHandler, ) } - @Throws(GenericException::class) - override fun `updateConsentState`(`state`: FfiConsentState) = - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_update_consent_state( - it, FfiConverterTypeFfiConsentState.lower(`state`), _status - ) - } - } - - - @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `updateGroupDescription`(`groupDescription`: kotlin.String) { + override suspend fun `streamAllDmMessages`(`messageCallback`: FfiMessageCallback): FfiStreamCloser { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_update_group_description( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_stream_all_dm_messages( thisPtr, - FfiConverterString.lower(`groupDescription`), + FfiConverterTypeFfiMessageCallback.lower(`messageCallback`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, // lift function - { Unit }, - + { FfiConverterTypeFfiStreamCloser.lift(it) }, // Error FFI converter - GenericException.ErrorHandler, + UniffiNullRustCallStatusErrorHandler, ) } - @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `updateGroupImageUrlSquare`(`groupImageUrlSquare`: kotlin.String) { + override suspend fun `streamAllGroupMessages`(`messageCallback`: FfiMessageCallback): FfiStreamCloser { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_update_group_image_url_square( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_stream_all_group_messages( thisPtr, - FfiConverterString.lower(`groupImageUrlSquare`), + FfiConverterTypeFfiMessageCallback.lower(`messageCallback`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, // lift function - { Unit }, - + { FfiConverterTypeFfiStreamCloser.lift(it) }, // Error FFI converter - GenericException.ErrorHandler, + UniffiNullRustCallStatusErrorHandler, ) } - @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `updateGroupName`(`groupName`: kotlin.String) { + override suspend fun `streamAllMessages`(`messageCallback`: FfiMessageCallback): FfiStreamCloser { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_update_group_name( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_stream_all_messages( thisPtr, - FfiConverterString.lower(`groupName`), + FfiConverterTypeFfiMessageCallback.lower(`messageCallback`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, // lift function - { Unit }, - + { FfiConverterTypeFfiStreamCloser.lift(it) }, // Error FFI converter - GenericException.ErrorHandler, + UniffiNullRustCallStatusErrorHandler, ) } - @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `updateGroupPinnedFrameUrl`(`pinnedFrameUrl`: kotlin.String) { + override suspend fun `streamDms`(`callback`: FfiConversationCallback): FfiStreamCloser { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_update_group_pinned_frame_url( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_stream_dms( thisPtr, - FfiConverterString.lower(`pinnedFrameUrl`), + FfiConverterTypeFfiConversationCallback.lower(`callback`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, // lift function - { Unit }, - + { FfiConverterTypeFfiStreamCloser.lift(it) }, // Error FFI converter - GenericException.ErrorHandler, + UniffiNullRustCallStatusErrorHandler, ) } - @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") - override suspend fun `updatePermissionPolicy`( - `permissionUpdateType`: FfiPermissionUpdateType, - `permissionPolicyOption`: FfiPermissionPolicy, - `metadataField`: FfiMetadataField?, - ) { + override suspend fun `streamGroups`(`callback`: FfiConversationCallback): FfiStreamCloser { return uniffiRustCallAsync( callWithPointer { thisPtr -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroup_update_permission_policy( + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_stream_groups( thisPtr, - FfiConverterTypeFfiPermissionUpdateType.lower(`permissionUpdateType`), - FfiConverterTypeFfiPermissionPolicy.lower(`permissionPolicyOption`), - FfiConverterOptionalTypeFfiMetadataField.lower(`metadataField`), + FfiConverterTypeFfiConversationCallback.lower(`callback`), ) }, { future, callback, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_pointer( future, callback, continuation ) }, { future, continuation -> - UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_pointer( future, continuation ) }, - { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_pointer(future) }, // lift function - { Unit }, - + { FfiConverterTypeFfiStreamCloser.lift(it) }, // Error FFI converter - GenericException.ErrorHandler, - ) - } - - - companion object - -} - -public object FfiConverterTypeFfiGroup : FfiConverter { - - override fun lower(value: FfiGroup): Pointer { - return value.uniffiClonePointer() - } - - override fun lift(value: Pointer): FfiGroup { - return FfiGroup(value) - } - - override fun read(buf: ByteBuffer): FfiGroup { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return lift(Pointer(buf.getLong())) - } - - override fun allocationSize(value: FfiGroup) = 8UL - - override fun write(value: FfiGroup, buf: ByteBuffer) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(lower(value))) - } -} - - -// This template implements a class for working with a Rust struct via a Pointer/Arc -// to the live Rust struct on the other side of the FFI. -// -// Each instance implements core operations for working with the Rust `Arc` and the -// Kotlin Pointer to work with the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an instance is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so risks -// leaking the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` -// is implemented to call the destructor when the Kotlin object becomes unreachable. -// This is done in a background thread. This is not a panacea, and client code should be aware that -// 1. the thread may starve if some there are objects that have poorly performing -// `drop` methods or do significant work in their `drop` methods. -// 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, -// or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// This makes a cleaner a better alternative to _not_ calling `destroy()` as -// and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` -// method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner -// thread may be starved, and the app will leak memory. -// -// In this case, `destroy`ing manually may be a better solution. -// -// The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects -// with Rust peers are reclaimed: -// -// 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: -// 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: -// 3. The memory is reclaimed when the process terminates. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// - - -public interface FfiGroupMetadataInterface { - - fun `conversationType`(): kotlin.String - - fun `creatorInboxId`(): kotlin.String - - companion object -} - -open class FfiGroupMetadata : Disposable, AutoCloseable, FfiGroupMetadataInterface { - - constructor(pointer: Pointer) { - this.pointer = pointer - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - /** - * This constructor can be used to instantiate a fake object. Only used for tests. Any - * attempt to actually use an object constructed this way will fail as there is no - * connected Rust object. - */ - @Suppress("UNUSED_PARAMETER") - constructor(noPointer: NoPointer) { - this.pointer = null - this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) - } - - protected val pointer: Pointer? - protected val cleanable: UniffiCleaner.Cleanable - - private val wasDestroyed = AtomicBoolean(false) - private val callCounter = AtomicLong(1) - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (!this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.uniffiClonePointer()) - } finally { - // This decrement always matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - cleanable.clean() - } - } - } - - // Use a static inner class instead of a closure so as not to accidentally - // capture `this` as part of the cleanable's action. - private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { - override fun run() { - pointer?.let { ptr -> - uniffiRustCall { status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_free_ffigroupmetadata(ptr, status) - } - } - } - } - - fun uniffiClonePointer(): Pointer { - return uniffiRustCall() { status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_clone_ffigroupmetadata(pointer!!, status) - } + UniffiNullRustCallStatusErrorHandler, + ) } - override fun `conversationType`(): kotlin.String { - return FfiConverterString.lift( - callWithPointer { - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroupmetadata_conversation_type( - it, _status + + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `sync`() { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_sync( + thisPtr, + ) - } - } + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_void( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_void( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_void(future) }, + // lift function + { Unit }, + + // Error FFI converter + GenericException.ErrorHandler, ) } - override fun `creatorInboxId`(): kotlin.String { - return FfiConverterString.lift( - callWithPointer { - uniffiRustCall() { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffigroupmetadata_creator_inbox_id( - it, _status + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `syncAllConversations`(): kotlin.UInt { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_fficonversations_sync_all_conversations( + thisPtr, + ) - } - } + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_u32( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_u32( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_u32(future) }, + // lift function + { FfiConverterUInt.lift(it) }, + // Error FFI converter + GenericException.ErrorHandler, ) } @@ -4483,25 +4768,25 @@ open class FfiGroupMetadata : Disposable, AutoCloseable, FfiGroupMetadataInterfa } -public object FfiConverterTypeFfiGroupMetadata : FfiConverter { +public object FfiConverterTypeFfiConversations : FfiConverter { - override fun lower(value: FfiGroupMetadata): Pointer { + override fun lower(value: FfiConversations): Pointer { return value.uniffiClonePointer() } - override fun lift(value: Pointer): FfiGroupMetadata { - return FfiGroupMetadata(value) + override fun lift(value: Pointer): FfiConversations { + return FfiConversations(value) } - override fun read(buf: ByteBuffer): FfiGroupMetadata { + override fun read(buf: ByteBuffer): FfiConversations { // The Rust code always writes pointers as 8 bytes, and will // fail to compile if they don't fit. return lift(Pointer(buf.getLong())) } - override fun allocationSize(value: FfiGroupMetadata) = 8UL + override fun allocationSize(value: FfiConversations) = 8UL - override fun write(value: FfiGroupMetadata, buf: ByteBuffer) { + override fun write(value: FfiConversations, buf: ByteBuffer) { // The Rust code always expects pointers written as 8 bytes, // and will fail to compile if they don't fit. buf.putLong(Pointer.nativeValue(lower(value))) @@ -6258,14 +6543,29 @@ public interface FfiXmtpClientInterface { `newWalletAddress`: kotlin.String, ): FfiSignatureRequest + /** + * * Get the inbox state for each `inbox_id`. + * * + * * If `refresh_from_network` is true, the client will go to the network first to refresh the state. + * * Otherwise, the state will be read from the local database. + */ + suspend fun `addressesFromInboxId`( + `refreshFromNetwork`: kotlin.Boolean, + `inboxIds`: List, + ): List + suspend fun `applySignatureRequest`(`signatureRequest`: FfiSignatureRequest) suspend fun `canMessage`(`accountAddresses`: List): Map + fun `conversation`(`conversationId`: kotlin.ByteArray): FfiConversation + fun `conversations`(): FfiConversations suspend fun `dbReconnect`() + fun `dmConversation`(`targetInboxId`: kotlin.String): FfiConversation + suspend fun `findInboxId`(`address`: kotlin.String): kotlin.String? suspend fun `getConsentState`( @@ -6275,8 +6575,6 @@ public interface FfiXmtpClientInterface { suspend fun `getLatestInboxState`(`inboxId`: kotlin.String): FfiInboxState - fun `group`(`groupId`: kotlin.ByteArray): FfiGroup - fun `inboxId`(): kotlin.String /** @@ -6435,6 +6733,48 @@ open class FfiXmtpClient : Disposable, AutoCloseable, FfiXmtpClientInterface { } + /** + * * Get the inbox state for each `inbox_id`. + * * + * * If `refresh_from_network` is true, the client will go to the network first to refresh the state. + * * Otherwise, the state will be read from the local database. + */ + @Throws(GenericException::class) + @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") + override suspend fun `addressesFromInboxId`( + `refreshFromNetwork`: kotlin.Boolean, + `inboxIds`: List, + ): List { + return uniffiRustCallAsync( + callWithPointer { thisPtr -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffixmtpclient_addresses_from_inbox_id( + thisPtr, + FfiConverterBoolean.lower(`refreshFromNetwork`), + FfiConverterSequenceString.lower(`inboxIds`), + ) + }, + { future, callback, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_poll_rust_buffer( + future, + callback, + continuation + ) + }, + { future, continuation -> + UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_complete_rust_buffer( + future, + continuation + ) + }, + { future -> UniffiLib.INSTANCE.ffi_xmtpv3_rust_future_free_rust_buffer(future) }, + // lift function + { FfiConverterSequenceTypeFfiInboxState.lift(it) }, + // Error FFI converter + GenericException.ErrorHandler, + ) + } + + @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") override suspend fun `applySignatureRequest`(`signatureRequest`: FfiSignatureRequest) { @@ -6499,6 +6839,21 @@ open class FfiXmtpClient : Disposable, AutoCloseable, FfiXmtpClientInterface { ) } + + @Throws(GenericException::class) + override fun `conversation`(`conversationId`: kotlin.ByteArray): FfiConversation { + return FfiConverterTypeFfiConversation.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffixmtpclient_conversation( + it, FfiConverterByteArray.lower(`conversationId`), _status + ) + } + } + ) + } + + override fun `conversations`(): FfiConversations { return FfiConverterTypeFfiConversations.lift( callWithPointer { @@ -6545,6 +6900,20 @@ open class FfiXmtpClient : Disposable, AutoCloseable, FfiXmtpClientInterface { } + @Throws(GenericException::class) + override fun `dmConversation`(`targetInboxId`: kotlin.String): FfiConversation { + return FfiConverterTypeFfiConversation.lift( + callWithPointer { + uniffiRustCallWithError(GenericException) { _status -> + UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffixmtpclient_dm_conversation( + it, FfiConverterString.lower(`targetInboxId`), _status + ) + } + } + ) + } + + @Throws(GenericException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") override suspend fun `findInboxId`(`address`: kotlin.String): kotlin.String? { @@ -6644,21 +7013,6 @@ open class FfiXmtpClient : Disposable, AutoCloseable, FfiXmtpClientInterface { ) } - - @Throws(GenericException::class) - override fun `group`(`groupId`: kotlin.ByteArray): FfiGroup { - return FfiConverterTypeFfiGroup.lift( - callWithPointer { - uniffiRustCallWithError(GenericException) { _status -> - UniffiLib.INSTANCE.uniffi_xmtpv3_fn_method_ffixmtpclient_group( - it, FfiConverterByteArray.lower(`groupId`), _status - ) - } - } - ) - } - - override fun `inboxId`(): kotlin.String { return FfiConverterString.lift( callWithPointer { @@ -6990,6 +7344,47 @@ public object FfiConverterTypeFfiConsent : FfiConverterRustBuffer { } +data class FfiConversationMember( + var `inboxId`: kotlin.String, + var `accountAddresses`: List, + var `installationIds`: List, + var `permissionLevel`: FfiPermissionLevel, + var `consentState`: FfiConsentState, +) { + + companion object +} + +public object FfiConverterTypeFfiConversationMember : + FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): FfiConversationMember { + return FfiConversationMember( + FfiConverterString.read(buf), + FfiConverterSequenceString.read(buf), + FfiConverterSequenceByteArray.read(buf), + FfiConverterTypeFfiPermissionLevel.read(buf), + FfiConverterTypeFfiConsentState.read(buf), + ) + } + + override fun allocationSize(value: FfiConversationMember) = ( + FfiConverterString.allocationSize(value.`inboxId`) + + FfiConverterSequenceString.allocationSize(value.`accountAddresses`) + + FfiConverterSequenceByteArray.allocationSize(value.`installationIds`) + + FfiConverterTypeFfiPermissionLevel.allocationSize(value.`permissionLevel`) + + FfiConverterTypeFfiConsentState.allocationSize(value.`consentState`) + ) + + override fun write(value: FfiConversationMember, buf: ByteBuffer) { + FfiConverterString.write(value.`inboxId`, buf) + FfiConverterSequenceString.write(value.`accountAddresses`, buf) + FfiConverterSequenceByteArray.write(value.`installationIds`, buf) + FfiConverterTypeFfiPermissionLevel.write(value.`permissionLevel`, buf) + FfiConverterTypeFfiConsentState.write(value.`consentState`, buf) + } +} + + data class FfiCreateGroupOptions( var `permissions`: FfiGroupPermissionsOptions?, var `groupName`: kotlin.String?, @@ -7095,46 +7490,6 @@ public object FfiConverterTypeFfiEnvelope : FfiConverterRustBuffer } -data class FfiGroupMember( - var `inboxId`: kotlin.String, - var `accountAddresses`: List, - var `installationIds`: List, - var `permissionLevel`: FfiPermissionLevel, - var `consentState`: FfiConsentState, -) { - - companion object -} - -public object FfiConverterTypeFfiGroupMember : FfiConverterRustBuffer { - override fun read(buf: ByteBuffer): FfiGroupMember { - return FfiGroupMember( - FfiConverterString.read(buf), - FfiConverterSequenceString.read(buf), - FfiConverterSequenceByteArray.read(buf), - FfiConverterTypeFfiPermissionLevel.read(buf), - FfiConverterTypeFfiConsentState.read(buf), - ) - } - - override fun allocationSize(value: FfiGroupMember) = ( - FfiConverterString.allocationSize(value.`inboxId`) + - FfiConverterSequenceString.allocationSize(value.`accountAddresses`) + - FfiConverterSequenceByteArray.allocationSize(value.`installationIds`) + - FfiConverterTypeFfiPermissionLevel.allocationSize(value.`permissionLevel`) + - FfiConverterTypeFfiConsentState.allocationSize(value.`consentState`) - ) - - override fun write(value: FfiGroupMember, buf: ByteBuffer) { - FfiConverterString.write(value.`inboxId`, buf) - FfiConverterSequenceString.write(value.`accountAddresses`, buf) - FfiConverterSequenceByteArray.write(value.`installationIds`, buf) - FfiConverterTypeFfiPermissionLevel.write(value.`permissionLevel`, buf) - FfiConverterTypeFfiConsentState.write(value.`consentState`, buf) - } -} - - data class FfiInboxState( var `inboxId`: kotlin.String, var `recoveryAddress`: kotlin.String, @@ -7275,7 +7630,7 @@ data class FfiMessage( var `convoId`: kotlin.ByteArray, var `senderInboxId`: kotlin.String, var `content`: kotlin.ByteArray, - var `kind`: FfiGroupMessageKind, + var `kind`: FfiConversationMessageKind, var `deliveryStatus`: FfiDeliveryStatus, ) { @@ -7290,7 +7645,7 @@ public object FfiConverterTypeFfiMessage : FfiConverterRustBuffer { FfiConverterByteArray.read(buf), FfiConverterString.read(buf), FfiConverterByteArray.read(buf), - FfiConverterTypeFfiGroupMessageKind.read(buf), + FfiConverterTypeFfiConversationMessageKind.read(buf), FfiConverterTypeFfiDeliveryStatus.read(buf), ) } @@ -7301,7 +7656,7 @@ public object FfiConverterTypeFfiMessage : FfiConverterRustBuffer { FfiConverterByteArray.allocationSize(value.`convoId`) + FfiConverterString.allocationSize(value.`senderInboxId`) + FfiConverterByteArray.allocationSize(value.`content`) + - FfiConverterTypeFfiGroupMessageKind.allocationSize(value.`kind`) + + FfiConverterTypeFfiConversationMessageKind.allocationSize(value.`kind`) + FfiConverterTypeFfiDeliveryStatus.allocationSize(value.`deliveryStatus`) ) @@ -7311,7 +7666,7 @@ public object FfiConverterTypeFfiMessage : FfiConverterRustBuffer { FfiConverterByteArray.write(value.`convoId`, buf) FfiConverterString.write(value.`senderInboxId`, buf) FfiConverterByteArray.write(value.`content`, buf) - FfiConverterTypeFfiGroupMessageKind.write(value.`kind`, buf) + FfiConverterTypeFfiConversationMessageKind.write(value.`kind`, buf) FfiConverterTypeFfiDeliveryStatus.write(value.`deliveryStatus`, buf) } } @@ -7567,7 +7922,7 @@ public object FfiConverterTypeFfiV2SubscribeRequest : enum class FfiConsentEntityType { - GROUP_ID, + CONVERSATION_ID, INBOX_ID, ADDRESS; @@ -7615,50 +7970,51 @@ public object FfiConverterTypeFfiConsentState : FfiConverterRustBuffer { +public object FfiConverterTypeFfiConversationMessageKind : + FfiConverterRustBuffer { override fun read(buf: ByteBuffer) = try { - FfiDeliveryStatus.values()[buf.getInt() - 1] + FfiConversationMessageKind.values()[buf.getInt() - 1] } catch (e: IndexOutOfBoundsException) { throw RuntimeException("invalid enum value, something is very wrong!!", e) } - override fun allocationSize(value: FfiDeliveryStatus) = 4UL + override fun allocationSize(value: FfiConversationMessageKind) = 4UL - override fun write(value: FfiDeliveryStatus, buf: ByteBuffer) { + override fun write(value: FfiConversationMessageKind, buf: ByteBuffer) { buf.putInt(value.ordinal + 1) } } -enum class FfiGroupMessageKind { +enum class FfiDeliveryStatus { - APPLICATION, - MEMBERSHIP_CHANGE; + UNPUBLISHED, + PUBLISHED, + FAILED; companion object } -public object FfiConverterTypeFfiGroupMessageKind : FfiConverterRustBuffer { +public object FfiConverterTypeFfiDeliveryStatus : FfiConverterRustBuffer { override fun read(buf: ByteBuffer) = try { - FfiGroupMessageKind.values()[buf.getInt() - 1] + FfiDeliveryStatus.values()[buf.getInt() - 1] } catch (e: IndexOutOfBoundsException) { throw RuntimeException("invalid enum value, something is very wrong!!", e) } - override fun allocationSize(value: FfiGroupMessageKind) = 4UL + override fun allocationSize(value: FfiDeliveryStatus) = 4UL - override fun write(value: FfiGroupMessageKind, buf: ByteBuffer) { + override fun write(value: FfiDeliveryStatus, buf: ByteBuffer) { buf.putInt(value.ordinal + 1) } } @@ -7986,7 +8342,7 @@ public object FfiConverterTypeSigningError : FfiConverterRustBuffer uniffiObj.`onConversation`( - FfiConverterTypeFfiGroup.lift(`conversation`), + FfiConverterTypeFfiConversation.lift(`conversation`), ) } val writeReturn = { _: Unit -> Unit } @@ -8648,24 +9004,25 @@ public object FfiConverterSequenceByteArray : FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { +public object FfiConverterSequenceTypeFfiConversation : + FfiConverterRustBuffer> { + override fun read(buf: ByteBuffer): List { val len = buf.getInt() - return List(len) { - FfiConverterTypeFfiGroup.read(buf) + return List(len) { + FfiConverterTypeFfiConversation.read(buf) } } - override fun allocationSize(value: List): ULong { + override fun allocationSize(value: List): ULong { val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypeFfiGroup.allocationSize(it) }.sum() + val sizeForItems = value.map { FfiConverterTypeFfiConversation.allocationSize(it) }.sum() return sizeForLength + sizeForItems } - override fun write(value: List, buf: ByteBuffer) { + override fun write(value: List, buf: ByteBuffer) { buf.putInt(value.size) value.iterator().forEach { - FfiConverterTypeFfiGroup.write(it, buf) + FfiConverterTypeFfiConversation.write(it, buf) } } } @@ -8694,6 +9051,31 @@ public object FfiConverterSequenceTypeFfiConsent : FfiConverterRustBuffer> { + override fun read(buf: ByteBuffer): List { + val len = buf.getInt() + return List(len) { + FfiConverterTypeFfiConversationMember.read(buf) + } + } + + override fun allocationSize(value: List): ULong { + val sizeForLength = 4UL + val sizeForItems = + value.map { FfiConverterTypeFfiConversationMember.allocationSize(it) }.sum() + return sizeForLength + sizeForItems + } + + override fun write(value: List, buf: ByteBuffer) { + buf.putInt(value.size) + value.iterator().forEach { + FfiConverterTypeFfiConversationMember.write(it, buf) + } + } +} + + public object FfiConverterSequenceTypeFfiEnvelope : FfiConverterRustBuffer> { override fun read(buf: ByteBuffer): List { val len = buf.getInt() @@ -8717,25 +9099,24 @@ public object FfiConverterSequenceTypeFfiEnvelope : FfiConverterRustBuffer> { - override fun read(buf: ByteBuffer): List { +public object FfiConverterSequenceTypeFfiInboxState : FfiConverterRustBuffer> { + override fun read(buf: ByteBuffer): List { val len = buf.getInt() - return List(len) { - FfiConverterTypeFfiGroupMember.read(buf) + return List(len) { + FfiConverterTypeFfiInboxState.read(buf) } } - override fun allocationSize(value: List): ULong { + override fun allocationSize(value: List): ULong { val sizeForLength = 4UL - val sizeForItems = value.map { FfiConverterTypeFfiGroupMember.allocationSize(it) }.sum() + val sizeForItems = value.map { FfiConverterTypeFfiInboxState.allocationSize(it) }.sum() return sizeForLength + sizeForItems } - override fun write(value: List, buf: ByteBuffer) { + override fun write(value: List, buf: ByteBuffer) { buf.putInt(value.size) value.iterator().forEach { - FfiConverterTypeFfiGroupMember.write(it, buf) + FfiConverterTypeFfiInboxState.write(it, buf) } } }