/*! \file */
/*******************************************
 *                                         *
 *  File auto-generated by `::safer_ffi`.  *
 *                                         *
 *  Do not manually edit this file.        *
 *                                         *
 *******************************************/

#ifndef __RUST_DITTOFFI__
#define __RUST_DITTOFFI__
#ifdef __cplusplus
extern "C" {
#endif


#include <stddef.h>
#include <stdint.h>

/** <No documentation available> */
#define DITTOFFI_PRESENCE_PEER_METADATA_MAX_SIZE_IN_BYTES ((uint32_t) 4096)

/** \brief
 *  Ditto Bluetooth Company ID.
 *
 *  According to the Android code, this is `0x0000`
 *  or `0` which according to the SIG Group, `0x0000` is "Ericsson Technology
 *  Licensing" which is not us but `0x0000` is used to match the other Ditto BLE
 *  implementations.
 */
#define DITTOFFI_TRANSPORTS_BLE_COMPANY_ID 0

/** \brief
 *  The layout of `&str` is opaque/subject to changes.
 */
typedef struct Opaque__str Opaque__str_t;

/** <No documentation available> */
#define DITTOFFI_TRANSPORTS_WIFI_AWARE_BACKGROUND_MODE_NAME "transports_wifi_aware_background_mode"

/** <No documentation available> */
#define DITTOFFI_TRANSPORTS_WIFI_AWARE_MAX_DATA_PATHS_OLDER_DEVICES_NAME "transports_wifi_aware_max_data_paths_older_devices"

/** <No documentation available> */
#define DITTOFFI_TRANSPORTS_WIFI_AWARE_MAX_ERROR_COUNT_NAME "transports_wifi_aware_max_error_count"

/** <No documentation available> */
#define DITTOFFI_TRANSPORTS_WIFI_AWARE_RECENT_ERROR_DURATION_MS_NAME "transports_wifi_aware_max_recent_error_duration_ms"

/** <No documentation available> */
#define DITTOFFI_TRANSPORTS_WIFI_AWARE_WIFI_SUBSYSTEM_RESET_ENABLED_NAME "transports_wifi_aware_enable_wifi_subsystem_reset_enabled"

/** \brief
 *  This enum contains all the Ditto types exposed publicly. The IDs **MUST**
 *  not be modified otherwise this would break the type conversions.
 *
 *  CHECKME: When merging with Russell's work on explicit types, this enum may
 *  be duplicated.
 */
typedef enum DittoCrdtType {
    /** <No documentation available> */
    DITTO_CRDT_TYPE_COUNTER = 0,
    /** <No documentation available> */
    DITTO_CRDT_TYPE_REGISTER = 1,
    /** <No documentation available> */
    DITTO_CRDT_TYPE_ATTACHMENT = 2,
    /** <No documentation available> */
    DITTO_CRDT_TYPE_RGA = 3,
    /** <No documentation available> */
    DITTO_CRDT_TYPE_R_W_MAP = 4,
    /** <No documentation available> */
    DITTO_CRDT_TYPE_ST_COUNTER = 5,
    /** <No documentation available> */
    DITTO_CRDT_TYPE_A_W_SET = 6,
} DittoCrdtType_t;

/** \brief
 *  State of WiFi Aware when the application goes to background
 */
typedef enum dittoffi_transport_wifi_aware_background_mode {
    /** \brief
     *  Try to keep WiFi Aware on
     */
    DITTOFFI_TRANSPORT_WIFI_AWARE_BACKGROUND_MODE_BEST_EFFORT_ON = 0,
    /** \brief
     *  Terminate WiFi Aware on background, and only if the device is on battery
     */
    DITTOFFI_TRANSPORT_WIFI_AWARE_BACKGROUND_MODE_OFF_ON_BATTERY_ONLY,
    /** \brief
     *  Terminate WiFi Aware on background
     */
    DITTOFFI_TRANSPORT_WIFI_AWARE_BACKGROUND_MODE_OFF,
} dittoffi_transport_wifi_aware_background_mode_t;

/** \brief
 *  A short-lived FFI object to let an SDK handle an authentication request
 *  in an async manner.
 */
typedef struct CAuthServerAuthRequest CAuthServerAuthRequest_t;

/** <No documentation available> */
void
/* fn */ auth_server_auth_submit_with_error (
    CAuthServerAuthRequest_t * req,
    uint32_t _error_code);

/** \brief
 *  `&'lt [T]` but with a guaranteed `#[repr(C)]` layout.
 *
 *  # C layout (for some given type T)
 *
 *  ```c
 *  typedef struct {
 *  // Cannot be NULL
 *  T * ptr;
 *  size_t len;
 *  } slice_T;
 *  ```
 *
 *  # Nullable pointer?
 *
 *  If you want to support the above typedef, but where the `ptr` field is
 *  allowed to be `NULL` (with the contents of `len` then being undefined)
 *  use the `Option< slice_ptr<_> >` type.
 */
typedef struct slice_ref_uint8 {
    /** \brief
     *  Pointer to the first element (if any).
     */
    uint8_t const * ptr;

    /** \brief
     *  Element count
     */
    size_t len;
} slice_ref_uint8_t;

/** <No documentation available> */
void
/* fn */ auth_server_auth_submit_with_success (
    CAuthServerAuthRequest_t * req,
    slice_ref_uint8_t success_cbor);

/** <No documentation available> */
typedef struct CAuthServerRefreshRequest CAuthServerRefreshRequest_t;

/** <No documentation available> */
void
/* fn */ auth_server_refresh_submit_with_error (
    CAuthServerRefreshRequest_t * req,
    uint32_t _error_code);

/** <No documentation available> */
void
/* fn */ auth_server_refresh_submit_with_success (
    CAuthServerRefreshRequest_t * req,
    slice_ref_uint8_t success_cbor);

/** \brief
 *  An opaque handle for each installed transport, heap-allocated and owned by
 *  the SDK.
 *
 *  A pointer to this handle is used to send platform events over FFI. In the
 *  future this handle will be the SDK's only point of control over the
 *  transport once created. In particular, a transport will be removed by
 *  freeing the handle. The concept of online and offline will be eliminated.
 *  (i.e., if you don't want a transport, remove it.)
 *
 *  For now, the `Peer` object holds the transports and provides an API based on
 *  a numeric id assigned to each transport instance. Until that is removed, the
 *  id still exists and the SDK can request it from the opaque handle over FFI.
 *
 *  For each transport type, define an `extern "C"` function to free that
 *  specific monomorphisation of the `TransportHandle` using `Box::from_raw`,
 *  plus a function to retrieve the transport id, which will be removed later.
 *
 *  Safety: The SDK owns the `TransportHandle`. It is responsible for ensuring
 *  that it does not use the pointer to the `TransportHandle` after freeing it
 *  with its respective function. In Rust we will assume it is okay to unsafely
 *  dereference a handle.
 *
 *  The C interface of `TransportHandle` is thread-safe (`Send + Sync`).
 */
typedef struct TransportHandle_BlePlatformEvent TransportHandle_BlePlatformEvent_t;

/** \brief
 *  Generic enum used by crate and platforms to indicate online-ness.
 *
 *  In other words, is something active or not? Not everything will use the
 *  transitional states.
 */
typedef enum OnlineState {
    /** <No documentation available> */
    ONLINE_STATE_OFFLINE,
    /** <No documentation available> */
    ONLINE_STATE_ONLINE,
    /** <No documentation available> */
    ONLINE_STATE_GOING_ONLINE,
    /** <No documentation available> */
    ONLINE_STATE_GOING_OFFLINE,
} OnlineState_t;

/** \brief
 *  A code reported by platforms/transports to indicate specific health
 *  conditions
 */
typedef enum TransportCondition {
    /** \brief
     *  A default state. Only use this for transient conditions, e.g., we are
     *  waiting for a platform to finish starting up. If everything is just
     *  quiet, use `Ok`.
     */
    TRANSPORT_CONDITION_UNKNOWN,
    /** \brief
     *  No known problems.
     */
    TRANSPORT_CONDITION_OK,
    /** \brief
     *  Catch-all failure, particularly for unexpected/internal faults. If
     *  possible, add a new case that the customer will be able to
     *  interpret.
     */
    TRANSPORT_CONDITION_GENERIC_FAILURE,
    /** \brief
     *  App is in background.
     */
    TRANSPORT_CONDITION_APP_IN_BACKGROUND,
    /** \brief
     *  We are not able to publish or discover with the mDNS daemon.
     */
    TRANSPORT_CONDITION_MDNS_FAILURE,
    /** \brief
     *  We cannot bind to a port.
     */
    TRANSPORT_CONDITION_TCP_LISTEN_FAILURE,
    /** \brief
     *  No app permission to act as a BLE Central.
     */
    TRANSPORT_CONDITION_NO_BLE_CENTRAL_PERMISSION,
    /** \brief
     *  No app permission to act as a BLE Peripheral.
     */
    TRANSPORT_CONDITION_NO_BLE_PERIPHERAL_PERMISSION,
    /** \brief
     *  This Transport targets a particular peer and we can't reach them right
     *  now.
     */
    TRANSPORT_CONDITION_CANNOT_ESTABLISH_CONNECTION,
    /** \brief
     *  The device has Bluetooth disabled at the OS level.
     */
    TRANSPORT_CONDITION_BLE_DISABLED,
    /** \brief
     *  The device has no Bluetooth hardware.
     */
    TRANSPORT_CONDITION_NO_BLE_HARDWARE,
    /** \brief
     *  The device has Wifi disabled at the OS level.
     */
    TRANSPORT_CONDITION_WIFI_DISABLED,
    /** \brief
     *  The platform has suspended briefly for internal reasons. Peers are
     *  reset.
     */
    TRANSPORT_CONDITION_TEMPORARILY_UNAVAILABLE,
} TransportCondition_t;

/** <No documentation available> */
void
/* fn */ ble_advertising_state_changed (
    TransportHandle_BlePlatformEvent_t const * handle,
    OnlineState_t state,
    TransportCondition_t result);

typedef struct {
    uint8_t idx[16];
} uint8_16_array_t;

/** <No documentation available> */
void
/* fn */ ble_central_finished_connecting (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * uuid,
    slice_ref_uint8_t announce,
    int32_t l2cap_available,
    uint32_t mtu);

/** <No documentation available> */
void
/* fn */ ble_central_l2cap_data_available (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * uuid);

/** <No documentation available> */
void
/* fn */ ble_central_l2cap_ready_to_send (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * uuid);

/** <No documentation available> */
void
/* fn */ ble_central_mtu_updated (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * uuid,
    uint32_t mtu);

/** <No documentation available> */
void
/* fn */ ble_central_ready_to_send (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * uuid);

/** <No documentation available> */
void
/* fn */ ble_central_unsubscribed (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * central_uuid);

/** \brief
 *  Generic enum used by crate and platforms to indicate a connection status
 */
typedef enum ConnectState {
    /** <No documentation available> */
    CONNECT_STATE_DISCONNECTED,
    /** <No documentation available> */
    CONNECT_STATE_CONNECTED,
    /** <No documentation available> */
    CONNECT_STATE_CONNECTING,
    /** <No documentation available> */
    CONNECT_STATE_DISCONNECTING,
} ConnectState_t;

/** <No documentation available> */
void
/* fn */ ble_connection_state_changed (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * peripheral_uuid,
    ConnectState_t state,
    int32_t l2cap_available,
    uint32_t mtu);

/** <No documentation available> */
void
/* fn */ ble_peripheral_l2cap_data_available (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * uuid);

/** <No documentation available> */
void
/* fn */ ble_peripheral_l2cap_ready_to_send (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * uuid);

/** <No documentation available> */
void
/* fn */ ble_peripheral_mtu_updated (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * uuid,
    uint32_t mtu);

/** <No documentation available> */
void
/* fn */ ble_peripheral_ready_to_send (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * uuid);

/** \brief
 *  When receiving data from a Bluetooth LE peer, such as a characteristic
 *  write, indicates what sort of data it is.
 */
typedef enum BleDataType {
    /** \brief
     *  The data _should_ contain the remote peer's announce string.
     *  Used during handshake.
     */
    BLE_DATA_TYPE_ANNOUNCE = 0,
    /** \brief
     *  Data message
     */
    BLE_DATA_TYPE_MESH_DATA = 1,
    /** \brief
     *  Control message
     */
    BLE_DATA_TYPE_CONTROL = 2,
} BleDataType_t;

/** <No documentation available> */
void
/* fn */ ble_received_from_central (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * central_uuid,
    BleDataType_t data_type,
    slice_ref_uint8_t data);

/** <No documentation available> */
void
/* fn */ ble_received_from_peripheral (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * peripheral_uuid,
    BleDataType_t data_type,
    slice_ref_uint8_t data);

/** <No documentation available> */
void
/* fn */ ble_scanning_state_changed (
    TransportHandle_BlePlatformEvent_t const * handle,
    OnlineState_t state,
    TransportCondition_t result);

/** <No documentation available> */
typedef struct CDitto CDitto_t;


#include <stdbool.h>

/** \brief
 *  Rust-level representation of the result of a send operation, converted from
 *  a bitfield
 */
typedef struct SendResult {
    /** <No documentation available> */
    bool accepted;

    /** <No documentation available> */
    bool wait_for_ready;
} SendResult_t;

/** \brief
 *  `&'lt mut [T]` but with a guaranteed `#[repr(C)]` layout.
 *
 *  # C layout (for some given type T)
 *
 *  ```c
 *  typedef struct {
 *  // Cannot be NULL
 *  T * ptr;
 *  size_t len;
 *  } slice_T;
 *  ```
 *
 *  # Nullable pointer?
 *
 *  If you want to support the above typedef, but where the `ptr` field is
 *  allowed to be `NULL` (with the contents of `len` then being undefined)
 *  use the `Option< slice_ptr<_> >` type.
 */
typedef struct slice_mut_uint8 {
    /** \brief
     *  Pointer to the first element (if any).
     */
    uint8_t * ptr;

    /** \brief
     *  Element count
     */
    size_t len;
} slice_mut_uint8_t;

/** <No documentation available> */
typedef struct BleClientCallbacks {
    /** <No documentation available> */
    void (*start_scanning)(void *, uint8_16_array_t const *, slice_ref_uint8_t);

    /** <No documentation available> */
    void (*stop_scanning)(void *);

    /** <No documentation available> */
    OnlineState_t (*scanning_state)(void *);

    /** <No documentation available> */
    void (*connect_peripheral)(void *, uint8_16_array_t const *);

    /** <No documentation available> */
    void (*disconnect_peripheral)(void *, uint8_16_array_t const *);

    /** <No documentation available> */
    SendResult_t (*write_to_peripheral)(void *, BleDataType_t, uint8_16_array_t const *, slice_ref_uint8_t);

    /** <No documentation available> */
    int32_t (*read_l2cap_from_peripheral)(void *, uint8_16_array_t const *, slice_mut_uint8_t);

    /** <No documentation available> */
    int32_t (*send_l2cap_to_peripheral)(void *, uint8_16_array_t const *, slice_ref_uint8_t);
} BleClientCallbacks_t;

/** <No documentation available> */
typedef struct BleServerCallbacks {
    /** <No documentation available> */
    void (*start_advertising)(void *, uint8_16_array_t const *, slice_ref_uint8_t);

    /** <No documentation available> */
    void (*stop_advertising)(void *);

    /** <No documentation available> */
    OnlineState_t (*advertising_state)(void *);

    /** <No documentation available> */
    SendResult_t (*notify_to_central)(void *, BleDataType_t, uint8_16_array_t const *, slice_ref_uint8_t);

    /** <No documentation available> */
    int32_t (*read_l2cap_from_central)(void *, uint8_16_array_t const *, slice_mut_uint8_t);

    /** <No documentation available> */
    int32_t (*send_l2cap_to_central)(void *, uint8_16_array_t const *, slice_ref_uint8_t);
} BleServerCallbacks_t;

/** <No documentation available> */
TransportHandle_BlePlatformEvent_t *
/* fn */ ditto_add_ble_transport (
    CDitto_t const * ditto,
    BleClientCallbacks_t client_callbacks,
    void * client_ctx,
    BleServerCallbacks_t server_callbacks,
    void * server_ctx,
    void (*retain)(void *),
    void (*release)(void *));

/** \brief
 *  The direction to sort the results of a query.
 */
typedef enum QuerySortDirection {
    /** <No documentation available> */
    QUERY_SORT_DIRECTION_ASCENDING = 1,
    /** <No documentation available> */
    QUERY_SORT_DIRECTION_DESCENDING,
} QuerySortDirection_t;

/** \brief
 *  OrderBy Parameter
 */
typedef struct COrderByParam {
    /** <No documentation available> */
    char const * query_c_str;

    /** <No documentation available> */
    QuerySortDirection_t direction;
} COrderByParam_t;

/** \brief
 *  `&'lt [T]` but with a guaranteed `#[repr(C)]` layout.
 *
 *  # C layout (for some given type T)
 *
 *  ```c
 *  typedef struct {
 *  // Cannot be NULL
 *  T * ptr;
 *  size_t len;
 *  } slice_T;
 *  ```
 *
 *  # Nullable pointer?
 *
 *  If you want to support the above typedef, but where the `ptr` field is
 *  allowed to be `NULL` (with the contents of `len` then being undefined)
 *  use the `Option< slice_ptr<_> >` type.
 */
typedef struct slice_ref_COrderByParam {
    /** \brief
     *  Pointer to the first element (if any).
     */
    COrderByParam_t const * ptr;

    /** \brief
     *  Element count
     */
    size_t len;
} slice_ref_COrderByParam_t;

/** <No documentation available> */
int32_t
/* fn */ ditto_add_subscription (
    CDitto_t const * ditto,
    char const * collection,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_by,
    int32_t limit,
    uint32_t offset);

/** <No documentation available> */
typedef struct LegacySubscriptionHandle LegacySubscriptionHandle_t;

/** <No documentation available> */
typedef struct LegacySubscriptionHandleResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    LegacySubscriptionHandle_t * handle;
} LegacySubscriptionHandleResult_t;

/** \brief
 *  Helper function for GC-sensitive SDKs to ensure proper unregistering of the subscription in the
 *  future.
 *
 *  Indeed, the state contained in the `LegacySubscriptionHandle` is otherwise difficult for the
 *  SDK to keep alive once "finalizing the world" has started: some of this state (such as some of
 *  the individual items of `order_by`) may have been disposed of already, which makes it impossible
 *  to then properly call `ditto_remove_subscription()`.
 */
LegacySubscriptionHandleResult_t
/* fn */ ditto_add_subscription_with_easier_unregistering (
    CDitto_t const * ditto,
    char const * collection,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_bys,
    int32_t limit,
    uint32_t offset);

/** <No documentation available> */
typedef struct WifiAwareClientCallbacks {
    /** <No documentation available> */
    void (*start_searching)(void *, char const *, char const *);

    /** <No documentation available> */
    void (*stop_searching)(void *);

    /** <No documentation available> */
    void (*create_network)(void *, char const *);

    /** <No documentation available> */
    void (*update_peer)(void *, char const *, ConnectState_t);
} WifiAwareClientCallbacks_t;

/** <No documentation available> */
typedef enum dittoffi_wifi_aware_system_parameter_u64 {
    /** <No documentation available> */
    DITTOFFI_WIFI_AWARE_SYSTEM_PARAMETER_U64_MAX_ERROR_COUNT,
    /** <No documentation available> */
    DITTOFFI_WIFI_AWARE_SYSTEM_PARAMETER_U64_RECENT_ERROR_DURATION_MS,
    /** <No documentation available> */
    DITTOFFI_WIFI_AWARE_SYSTEM_PARAMETER_U64_BACKGROUND_MODE,
} dittoffi_wifi_aware_system_parameter_u64_t;

/** <No documentation available> */
typedef struct WifiAwareServerCallbacks {
    /** <No documentation available> */
    void (*start_advertising)(void *, char const *, char const *, uint16_t);

    /** <No documentation available> */
    void (*stop_advertising)(void *);

    /** <No documentation available> */
    void (*update_peer)(void *, char const *, ConnectState_t);

    /** <No documentation available> */
    void (*update_parameter_u64)(void *, dittoffi_wifi_aware_system_parameter_u64_t, uint64_t);
} WifiAwareServerCallbacks_t;

/** \brief
 *  An opaque handle for each installed transport, heap-allocated and owned by
 *  the SDK.
 *
 *  A pointer to this handle is used to send platform events over FFI. In the
 *  future this handle will be the SDK's only point of control over the
 *  transport once created. In particular, a transport will be removed by
 *  freeing the handle. The concept of online and offline will be eliminated.
 *  (i.e., if you don't want a transport, remove it.)
 *
 *  For now, the `Peer` object holds the transports and provides an API based on
 *  a numeric id assigned to each transport instance. Until that is removed, the
 *  id still exists and the SDK can request it from the opaque handle over FFI.
 *
 *  For each transport type, define an `extern "C"` function to free that
 *  specific monomorphisation of the `TransportHandle` using `Box::from_raw`,
 *  plus a function to retrieve the transport id, which will be removed later.
 *
 *  Safety: The SDK owns the `TransportHandle`. It is responsible for ensuring
 *  that it does not use the pointer to the `TransportHandle` after freeing it
 *  with its respective function. In Rust we will assume it is okay to unsafely
 *  dereference a handle.
 *
 *  The C interface of `TransportHandle` is thread-safe (`Send + Sync`).
 */
typedef struct TransportHandle_WifiAwarePlatformEvent TransportHandle_WifiAwarePlatformEvent_t;

/** <No documentation available> */
TransportHandle_WifiAwarePlatformEvent_t *
/* fn */ ditto_add_wifi_aware_transport (
    CDitto_t const * ditto,
    WifiAwareClientCallbacks_t client_callbacks,
    WifiAwareServerCallbacks_t server_callbacks,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *));

/** <No documentation available> */
char *
/* fn */ ditto_auth_client_get_app_id (
    CDitto_t const * ditto);

/** <No documentation available> */
uint64_t
/* fn */ ditto_auth_client_get_site_id (
    CDitto_t const * ditto);

/** <No documentation available> */
int32_t
/* fn */ ditto_auth_client_is_web_valid (
    CDitto_t const * ditto);

/** <No documentation available> */
int32_t
/* fn */ ditto_auth_client_login_with_credentials (
    CDitto_t * ditto,
    char const * username,
    char const * password,
    char const * provider);

/** <No documentation available> */
int32_t
/* fn */ ditto_auth_client_login_with_token (
    CDitto_t * ditto,
    char const * token,
    char const * provider);

/** <No documentation available> */
typedef struct BoxedCharPtrResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    char * c_string;
} BoxedCharPtrResult_t;

/** <No documentation available> */
BoxedCharPtrResult_t
/* fn */ ditto_auth_client_login_with_token_and_feedback (
    CDitto_t const * ditto,
    char const * token,
    char const * provider);

/** \brief
 *  Trigger an explicit logout and purge of any cached credentials
 */
int32_t
/* fn */ ditto_auth_client_logout (
    CDitto_t const * ditto);

/** \brief
 *  An `SdkLoginProvider` that sends the notifications over FFI
 */
typedef struct CLoginProvider CLoginProvider_t;

/** \brief
 *  Create a LoginProvider. Ownership passes to the SDK.
 *
 *  This cannot be freed directly - it should be passed in when creating an
 *  AuthClient.
 */
CLoginProvider_t *
/* fn */ ditto_auth_client_make_login_provider (
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*expiring_cb)(void *, uint32_t));

/** <No documentation available> */
char *
/* fn */ ditto_auth_client_user_id (
    CDitto_t const * ditto);

/** <No documentation available> */
void
/* fn */ ditto_auth_login_provider_free (
    CLoginProvider_t * login_provider);

/** <No documentation available> */
void
/* fn */ ditto_auth_set_login_provider (
    CDitto_t const * ditto,
    CLoginProvider_t * login_provider);

/** \brief
 *  The SDK requests to drop its handle to the BLE Transport
 *
 *  At some point dropping this events channel will effectively shut down and
 *  remove the Transport. At time of writing, the Transport is still owned
 *  within Peer.
 */
void
/* fn */ ditto_ble_transport_free_handle (
    TransportHandle_BlePlatformEvent_t * handle);

/** \brief
 *  [`Box`][`rust::Box`]`<[T]>` (fat pointer to a slice),
 *  but with a guaranteed `#[repr(C)]` layout.
 *
 *  # C layout (for some given type T)
 *
 *  ```c
 *  typedef struct {
 *  // Cannot be NULL
 *  T * ptr;
 *  size_t len;
 *  } slice_T;
 *  ```
 *
 *  # Nullable pointer?
 *
 *  If you want to support the above typedef, but where the `ptr` field is
 *  allowed to be `NULL` (with the contents of `len` then being undefined)
 *  use the `Option< slice_ptr<_> >` type.
 */
typedef struct slice_boxed_uint8 {
    /** \brief
     *  Pointer to the first element (if any).
     */
    uint8_t * ptr;

    /** \brief
     *  Element count
     */
    size_t len;
} slice_boxed_uint8_t;

/** \brief
 *  Releases a byte array value returned by DittoStore.
 *
 *  DittoStore manages its own memory allocations and it is not safe to release
 *  such values with C's `free()`. That's why the structures it returns provide
 *  their own associated `free` function.
 *
 *  It should be used for values returned by functions like
 *  `ditto_document_cbor`.
 */
void
/* fn */ ditto_c_bytes_free (
    slice_boxed_uint8_t bytes);

/** \brief
 *  Releases `char *` value returned by DittoStore.
 *
 *  DittoStore manages its own memory allocations and it is not safe to release
 *  such values with C's `free()`. That's why the structures it returns provide
 *  their own associated `free` function and this is one we need for `char *`.
 *
 *  It should be used for values returned by functions like
 *  `ditto_document_id_query_compatible`.
 */
void
/* fn */ ditto_c_string_free (
    char * s);

/** <No documentation available> */
typedef struct DittoCancellable DittoCancellable_t;

/** <No documentation available> */
void
/* fn */ ditto_cancel (
    DittoCancellable_t * _cancelable);

/** \brief
 *  Cancels a resolve callback registered by ditto_resolve_attachment.
 *
 *  Returns following error codes:
 *
 *  * `0` -- no error
 *  * `1` -- an error
 *  * `2` -- invalid id
 *  * `3` -- token never issued
 *
 *  In case of a non-zero return value, error message can be retrieved using
 *  `ditto_error_message` function.
 */
uint32_t
/* fn */ ditto_cancel_resolve_attachment (
    CDitto_t const * ditto,
    slice_ref_uint8_t id,
    uint64_t cancel_token);

/** \brief
 *  The `PathAccessorType` enum allows you to specify (usually from the SDK side
 *  of the FFI) what sort of type you’re trying to access. So for some of the
 *  cases in the enum, e.g. `String`, `Bool`, etc, it’s quite straightforward
 *  what you’re asking for. For something like `Int` it’s a little more complex
 *  in that if the value at the path you’ve provided is an integer _or_ a float
 *  (with no fractional part to it) then it’ll return an integer to you. For
 *  `Array` or `Object` it’ll give you back an array or an object (respectively)
 *  if either the value at the path provided is a `Register` containing an
 *  array/object or if the value at the path provided is an `RGA`/`RWMap`,
 *  respectively.
 *
 *  There are then the explicit type accessor type cases in that enum, e.g.
 *  `Counter`, `Register`, etc which will only return a value if the “active”
 *  value (most recently updated) at the provided path is a CRDT of the
 *  specified type, otherwise `None` will be returned.
 */
typedef enum PathAccessorType {
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_STRING,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_NUMBER,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_INT,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_U_INT,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_FLOAT,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_DOUBLE,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_BOOL,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_NULL,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_OBJECT,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_ARRAY,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_ANY,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_COUNTER,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_REGISTER,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_ATTACHMENT,
    /** <No documentation available> */
    PATH_ACCESSOR_TYPE_R_W_MAP,
} PathAccessorType_t;

/** <No documentation available> */
typedef struct CBORPathResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    slice_boxed_uint8_t cbor;
} CBORPathResult_t;

/** \brief
 *  Gets the CBOR value at the path in the provided CBOR and returns it if the
 *  value found matches the type requested, otherwise `None` will be returned in
 *  the result.
 *
 *  If CBOR is returned in the result then the bytes have to be released with
 *  `::ditto_c_bytes_free`.
 */
CBORPathResult_t
/* fn */ ditto_cbor_get_cbor_with_path_type (
    slice_ref_uint8_t cbor,
    char const * path,
    PathAccessorType_t path_type);

/** \brief
 *  Represents the error code as returned by various FFI functions. It's a
 *  simple integer for now, the codes are specified by each FFI function
 *  individually (for now, we plan to introduce a proper error type in the near
 *  future).
 *  Beware that all errors are not captured here. It is encouraged to use this enum
 *  instead of explicit `status_code` -mostly 0 and 1-.
 */
typedef enum DittoErrorCode {
    /** <No documentation available> */
    DITTO_ERROR_CODE_OK = 0,
    /** <No documentation available> */
    DITTO_ERROR_CODE_UNKNOWN = 1,
    /** <No documentation available> */
    DITTO_ERROR_CODE_NOT_IMPLEMENTED = 2,
    /** \brief
     *  Fatal case that ought to never happen.
     */
    DITTO_ERROR_CODE_UNREACHABLE = 2989,
    /** <No documentation available> */
    DITTO_ERROR_CODE_FAILED_TO_ACQUIRE_LOCK_FILE = 16777217,
    /** <No documentation available> */
    DITTO_ERROR_CODE_INVALID_PASSPHRASE = 33554433,
    /** <No documentation available> */
    DITTO_ERROR_CODE_EXTRANEOUS_PASSPHRASE_GIVEN = 33554434,
    /** <No documentation available> */
    DITTO_ERROR_CODE_PASSPHRASE_NOT_GIVEN = 33554435,
    /** <No documentation available> */
    DITTO_ERROR_CODE_ALREADY_ENCRYPTED = 33554436,
    /** <No documentation available> */
    DITTO_ERROR_CODE_ENCRYPTION_FAILED = 33554437,
    /** <No documentation available> */
    DITTO_ERROR_CODE_CANNOT_BE_ENCRYPTED = 33554438,
    /** <No documentation available> */
    DITTO_ERROR_CODE_NOT_INITIALIZED = 33554439,
    /** <No documentation available> */
    DITTO_ERROR_CODE_SORT_FAILED = 50331649,
    /** <No documentation available> */
    DITTO_ERROR_CODE_DQL_FAILED_TO_COMPILE_QUERY = 50331650,
    /** <No documentation available> */
    DITTO_ERROR_CODE_DQL_UNSUPPORTED = 50331651,
    /** <No documentation available> */
    DITTO_ERROR_CODE_DQL_EXECUTION_FAILED = 50331652,
    /** <No documentation available> */
    DITTO_ERROR_CODE_PARAMETER_QUERY_FAILED = 50331653,
} DittoErrorCode_t;

/** \brief
 *  Changes the passphrase and re-encrypts all data. This can take a while,
 *  progress is reported via the progress callback. Returns a progress token
 *  or 0 if a _synchronous_ error occured, in which case the `error_code` out
 *  parameter is set (see error code table below).
 *
 *  Note that errors can also occur while the operation is in progress. Those
 *  are typically IO errors and are reported via the progress callback.
 *  The combination of `passphrase` and `newPassphrase` have the following
 *  effects:
 *
 *  - `passphrase = NULL` & `newPassphrase = NULL` -> No-op if not encrypted, otherwise error code
 *  3.
 *
 *  - `passphrase = "123"` & `newPassphrase = "123"` -> No-op if encrypted and password is correct,
 *  error code 2 if not encrypted, and error code 1 if encrypted but `passphrase` invalid.
 *
 *  - `passphrase = NULL` & `newPassphrase = "123"` -> Add encryption. No-op if already encrypted
 *  and passphrase matches, error code 4 if already encrypted but passphrase does not match.
 *
 *  - `passphrase = "123"` & `newPassphrase = NULL` -> Remove encryption. No op
 *  - if not encrypted.
 *
 *  - `passphrase = "123"` & `newPassphrase = "456"` -> Re-encrypt. Error code 1 if passphrase
 *  invalid.
 */
DittoCancellable_t *
/* fn */ ditto_change_passphrase (
    char const * _working_dir,
    char const * _old_passphrase,
    char const * _new_passphrase,
    void * _ctx,
    void (*_c_cb)(void *),
    DittoErrorCode_t * _error_code);

/** \brief
 *  Deregister any presence callback, releasing the receiver on the SDK side.
 */
void
/* fn */ ditto_clear_presence_callback (
    CDitto_t const * ditto);

/** \brief
 *  Deregister v3 presence callback, releasing the receiver on the SDK side.
 */
void
/* fn */ ditto_clear_presence_v3_callback (
    CDitto_t const * ditto);

/** <No documentation available> */
int32_t
/* fn */ ditto_collection (
    CDitto_t const * ditto,
    char const * name);

/** \brief
 *  Write transaction synchronous API.
 */
typedef struct CWriteTransaction CWriteTransaction_t;

/** <No documentation available> */
typedef struct BoolResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    bool bool_value;
} BoolResult_t;

/** \brief
 *  Evict a document from the collection, using the provided write transaction.
 *
 *  `was_evicted` is set to indicate whether the document was removed
 *  successfully.
 *
 *  * [js only] Returns -1 in case of outstanding non-`await`ed transaction operation.
 */
BoolResult_t
/* fn */ ditto_collection_evict (
    CDitto_t const * ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    slice_ref_uint8_t id);

/** \brief
 *  `&'lt [T]` but with a guaranteed `#[repr(C)]` layout.
 *
 *  # C layout (for some given type T)
 *
 *  ```c
 *  typedef struct {
 *  // Cannot be NULL
 *  T * ptr;
 *  size_t len;
 *  } slice_T;
 *  ```
 *
 *  # Nullable pointer?
 *
 *  If you want to support the above typedef, but where the `ptr` field is
 *  allowed to be `NULL` (with the contents of `len` then being undefined)
 *  use the `Option< slice_ptr<_> >` type.
 */
typedef struct slice_ref_slice_boxed_uint8 {
    /** \brief
     *  Pointer to the first element (if any).
     */
    slice_boxed_uint8_t const * ptr;

    /** \brief
     *  Element count
     */
    size_t len;
} slice_ref_slice_boxed_uint8_t;

/** \brief
 *  Same as [`Vec<T>`][`rust::Vec`], but with guaranteed `#[repr(C)]` layout
 */
typedef struct Vec_slice_boxed_uint8 {
    /** <No documentation available> */
    slice_boxed_uint8_t * ptr;

    /** <No documentation available> */
    size_t len;

    /** <No documentation available> */
    size_t cap;
} Vec_slice_boxed_uint8_t;

/** <No documentation available> */
typedef struct DocIdsResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    Vec_slice_boxed_uint8_t ids;
} DocIdsResult_t;

/** \brief
 *  Evict several documents from the collection, using the provided write transaction.
 *
 *  Returns the list of successfully evicted document ids.
 *
 *  * [js only] Returns -1 in case of outstanding non-`await`ed transaction operation.
 */
DocIdsResult_t
/* fn */ ditto_collection_evict_by_ids (
    CDitto_t const * ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    slice_ref_slice_boxed_uint8_t ids);

/** \brief
 *  Evict all documents returned by the specified query from a collection.
 *
 *  `out_ids` is set to the list of IDs of all documents successfully evicted.
 *
 *  [js only] Returns -2 in case of outstanding non-awaited transaction operation.
 */
DocIdsResult_t
/* fn */ ditto_collection_evict_query_str (
    CDitto_t const * ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_by_params,
    int32_t limit,
    uint32_t offset);

/** \brief
 *  Store document consisting of a `DocumentId` and `ditto_crdt::Document` pair.
 *
 *  Within the `ditto_store` crate the association of these two elements is maintained together
 *  within this single structure, while these elements may be stored separately in upstream or
 *  downstream crates. This type corresponds to the `Record` type in the `replication` crate, rather
 *  than a literal document.
 */
typedef struct CDocument CDocument_t;

/** \brief
 *  Same as [`Vec<T>`][`rust::Vec`], but with guaranteed `#[repr(C)]` layout
 */
typedef struct Vec_CDocument_ptr {
    /** <No documentation available> */
    CDocument_t * * ptr;

    /** <No documentation available> */
    size_t len;

    /** <No documentation available> */
    size_t cap;
} Vec_CDocument_ptr_t;

/** <No documentation available> */
typedef struct DocumentsResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    Vec_CDocument_ptr_t documents;
} DocumentsResult_t;

/** \brief
 *  Execute the specified query.
 *
 *  `out_documents` is set to the list of all documents successfully retrieved
 *  from the collection.
 *
 *  [js only] Returns -2 in case of outstanding non-awaited transaction operation.
 */
DocumentsResult_t
/* fn */ ditto_collection_exec_query_str (
    CDitto_t const * ditto,
    char const * coll_name,
    CWriteTransaction_t * txn,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_by_params,
    int32_t limit,
    uint32_t offset);

/** \brief
 *  Read transaction synchronous API.
 */
typedef struct CReadTransaction CReadTransaction_t;

/** <No documentation available> */
typedef struct DocumentsIdsResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    Vec_CDocument_ptr_t documents;

    /** <No documentation available> */
    Vec_slice_boxed_uint8_t ids;
} DocumentsIdsResult_t;

/** \brief
 *  [js only] Returns `-1` in case of outstanding non-`awaited` transaction operation.
 */
DocumentsIdsResult_t
/* fn */ ditto_collection_find_by_ids (
    CDitto_t const * ditto,
    char const * coll_name,
    slice_ref_slice_boxed_uint8_t ids,
    CReadTransaction_t * transaction);

/** <No documentation available> */
typedef struct DocumentResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    CDocument_t * document;
} DocumentResult_t;

/** \brief
 *  [js only] Returns `-1` in case of outstanding non-`awaited` transaction operation.
 */
DocumentResult_t
/* fn */ ditto_collection_get (
    CDitto_t const * _ditto,
    char const * coll_name,
    slice_ref_uint8_t id,
    CReadTransaction_t * transaction);

/** \brief
 *  [js only] Returns `-1` in case of outstanding non-`awaited` transaction operation.
 */
DocumentResult_t
/* fn */ ditto_collection_get_with_write_transaction (
    CDitto_t const * _ditto,
    char const * coll_name,
    slice_ref_uint8_t id,
    CWriteTransaction_t * transaction);

/** \brief
 *  The write strategies available when writing data to the store.
 */
typedef enum WriteStrategyRs {
    /** \brief
     *  Create or merge with existing data
     */
    WRITE_STRATEGY_RS_MERGE,
    /** \brief
     *  Only insert if no document already exists with the same document ID
     */
    WRITE_STRATEGY_RS_INSERT_IF_ABSENT,
    /** \brief
     *  Insert as default data, only if no document already exists with the same document ID
     */
    WRITE_STRATEGY_RS_INSERT_DEFAULT_IF_ABSENT,
    /** \brief
     *  This works as follows:
     *  - If the document does not exist, it is created with the given value
     *  - If the document exists, the value is compared to the document's current value, any
     *  differing leaf's values in the Document are updated to match the given value. Nothing is
     *  removed.
     */
    WRITE_STRATEGY_RS_UPDATE_DIFFERENT_VALUES,
} WriteStrategyRs_t;

/** <No documentation available> */
typedef struct DocIdResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    slice_boxed_uint8_t id;
} DocIdResult_t;

/** \brief
 *  Inserts a document into the store.
 *
 *  If an ID is provided explicitly via the `doc_id` parameter then that will be
 *  used as the document's ID. If an ID is provided implicitly via the
 *  document's value (`doc_cbor`) then that will be used as the document's ID,
 *  assuming no explicit ID was provided. If neither an explicit nor an implicit
 *  document ID was provided then a new document ID will be generated and used
 *  as the new document's ID.
 *
 *  Return codes:
 *
 *  * `0` -- success
 *  * `1` -- improper CBOR provided for the document value
 *  * `2` -- invalid CBOR for the document value (i.e. the CBOR could be parsed but it represented a
 *  non-`Object` value)
 *  * `3` -- unable to create document ID from value at `_id` key in document's value (`doc_cbor`
 *  argument)
 *  * `4` -- (js only) concurrent database operation (missing `await`?)
 */
DocIdResult_t
/* fn */ ditto_collection_insert_value (
    CDitto_t const * ditto,
    char const * coll_name,
    slice_ref_uint8_t doc_cbor,
    WriteStrategyRs_t write_strategy,
    char const * log_hint,
    CWriteTransaction_t * txn);

/** \brief
 *  Remove a document from the collection, using the provided write transaction.
 *
 *  `was_removed` is set to indicate whether the document was removed
 *  successfully.
 *
 *  * [js only] Returns -1 in case of outstanding non-`await`ed transaction operation.
 */
BoolResult_t
/* fn */ ditto_collection_remove (
    CDitto_t const * _ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    slice_ref_uint8_t id);

/** \brief
 *  Remove documents from the collection, using the provided write transaction.
 *
 *  Return the list of successfully removed DocumentId
 *
 *  Will return an error if the number of keys is greater than 1024.
 *  * [js only] Returns -1 in case of outstanding non-`await`ed transaction operation.
 */
DocIdsResult_t
/* fn */ ditto_collection_remove_by_ids (
    CDitto_t const * ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    slice_ref_slice_boxed_uint8_t ids);

/** \brief
 *  Remove all documents returned by the specified query from a collection.
 *
 *  `out_ids` is set to the list of IDs of all documents successfully removed.
 *
 *  [js only] Returns -2 in case of outstanding non-awaited transaction operation.
 */
DocIdsResult_t
/* fn */ ditto_collection_remove_query_str (
    CDitto_t const * ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_by_params,
    int32_t limit,
    uint32_t offset);

/** \brief
 *  [js only] Returns -1 in case of outstanding non-awaited transaction operation.
 */
int32_t
/* fn */ ditto_collection_update (
    CDitto_t const * _ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    CDocument_t * document);

/** \brief
 *  Update multiple documents in a collection, using the provided write
 *  transaction.
 *
 *  # Return Values
 *
 *  - Returns `0` if all links were successfully updated in all documents.
 *  - Returns `-1` if one or more documents' links fail to all update
 *  successfully, but all documents themselves are successfully updated. Note
 *  that in the event of an attachment failing to update, updates are still
 *  attempted on the rest of the attachments and the rest of the documents.
 *  - If a document fails to update, the appropriate error code is returned for
 *  the cause of the failure. Note that if a document fails to update, no more
 *  document updates are attempted.
 */
int32_t
/* fn */ ditto_collection_update_multiple (
    CDitto_t const * _ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    Vec_CDocument_ptr_t documents);

/** <No documentation available> */
int32_t
/* fn */ ditto_disable_sync_with_v3 (
    CDitto_t const * ditto);

/** \brief
 *  Supported components whose disk usage can be monitored separately.
 */
/** \remark Has the same ABI as `uint8_t` **/
#ifdef DOXYGEN
typedef
#endif
enum FsComponent {
    /** \brief
     *  The whole ditto working directory
     */
    FS_COMPONENT_ROOT = 0,
    /** \brief
     *  The store component
     */
    FS_COMPONENT_STORE,
    /** \brief
     *  The auth component
     */
    FS_COMPONENT_AUTH,
    /** \brief
     *  The replication component
     */
    FS_COMPONENT_REPLICATION,
    /** \brief
     *  The attachment component
     */
    FS_COMPONENT_ATTACHMENT,
}
#ifndef DOXYGEN
; typedef uint8_t
#endif
FsComponent_t;

/** \brief
 *  Get a cbor repr of the disk usage
 */
slice_boxed_uint8_t
/* fn */ ditto_disk_usage (
    CDitto_t const * ditto,
    FsComponent_t path);

/** \brief
 *  Document's CBOR
 */
slice_boxed_uint8_t
/* fn */ ditto_document_cbor (
    CDocument_t const * document);

/** \brief
 *  Releases the document
 */
void
/* fn */ ditto_document_free (
    CDocument_t * document);

/** \brief
 *  Gets the CBOR value at the path in the provided document and returns it if
 *  the value found matches the type requested, otherwise `None` will be
 *  returned in the result.
 *
 *  To understand how this is intended to be used it might be instructive to see
 *  how things work in the DittoDocumentPath of the Swift SDK, for example:
 *  <https://github.com/getditto/ditto/blob/v2/cocoa/DittoSwift/Store/DittoDocumentPath.swift#L63-L277>
 *
 *  where the valueAtPathInDocumentWithType implementation looks like this:
 *  <https://github.com/getditto/ditto/blob/259cfa64dd2c6b36ffee2e97514695ccbfff6755/cocoa/DittoSwift/Store/Internal/ValueAtPath.swift#L42-L49>
 *
 *  Note: all the of the values returned by
 *  `ditto_document_get_cbor_with_path_type` are untyped (i.e. there’s never an
 *  object with `_value` and `_ditto_internal_type_jkb12973t4b` keys being
 *  returned). For example, if you request a value at a path with a
 *  `PathAccessorType` of `Counter` and there is indeed a counter at that path
 *  then the value (as CBOR) that will be returned will be the `f64`/`double`
 *  representation of the counter’s value, on its own.
 *
 *  If CBOR is returned in the result then the bytes have to be released with
 *  `::ditto_c_bytes_free`.
 */
CBORPathResult_t
/* fn */ ditto_document_get_cbor_with_path_type (
    CDocument_t const * document,
    char const * pointer,
    PathAccessorType_t path_type);

/** \brief
 *  Document's ID
 *
 *  The resulting bytes have to be freed with `::ditto_c_bytes_free`
 */
slice_boxed_uint8_t
/* fn */ ditto_document_id (
    CDocument_t const * document);

/** \brief
 *  Defines how string primitives should be encoded. This is relevant if a
 *  document ID was created from a string. There are occasions when we want the
 *  stringified representation of the document ID do include quotes around the
 *  string, for example when creating a query like `_id == "abc"`. However,
 *  there are also times when we want to return the string as just a string, for
 *  example when we're injecting a document ID into a document's value before
 *  then serializing the document and sending those bytes across the FFI
 *  boundary.
 */
typedef enum StringPrimitiveFormat {
    /** <No documentation available> */
    STRING_PRIMITIVE_FORMAT_WITH_QUOTES,
    /** <No documentation available> */
    STRING_PRIMITIVE_FORMAT_WITHOUT_QUOTES,
} StringPrimitiveFormat_t;

/** \brief
 *  Convert a document ID from CBOR bytes into a Ditto query language compatible
 *  string.
 *
 *  The resulting string has to be freed with `::ditto_c_string_free`
 */
char *
/* fn */ ditto_document_id_query_compatible (
    slice_ref_uint8_t id,
    StringPrimitiveFormat_t string_primitive_format);

/** <No documentation available> */
int32_t
/* fn */ ditto_document_increment_counter (
    CDocument_t * document,
    char const * pointer,
    double amount);

/** \brief
 *  Removes a value from a document. Only object properties can be removed. If the
 *  `pointer` points to an array index, the removal will fail. To update an array
 *  within a register, see `ditto_document_update`.
 *
 *  # Arguments
 *
 *  * `document` - A pointer to the document which was previously returned from a query.
 *  * `pointer` - A JMESPath _pointer_ to a property within `document` which is to be removed.
 *
 *  # Returns
 *
 *  `0` if the remove was successful or non-zero to indicate failure. To
 *  retrieve an error message in the case of failure, call
 *  `ditto_error_message()`.
 */
int32_t
/* fn */ ditto_document_remove (
    CDocument_t * document,
    char const * pointer);

/** <No documentation available> */
int32_t
/* fn */ ditto_document_set_cbor (
    CDocument_t * document,
    char const * pointer,
    slice_ref_uint8_t cbor);

/** <No documentation available> */
int32_t
/* fn */ ditto_document_set_cbor_with_timestamp (
    CDocument_t * document,
    char const * pointer,
    slice_ref_uint8_t cbor,
    uint32_t _timestamp);

/** \brief
 *  Updates the document with values taken from provided CBOR data.
 *
 *  Returns following error codes:
 *
 *  * `0` -- no error
 *  * `1` -- invalid CBOR data
 *  * `2` -- CBOR data was not a map
 *  * `3` -- update error
 *  * `4` -- `_id` key provided
 *  * `5` -- invalid value
 *
 *  In case of a non-zero return value, error message can be retrieved using
 *  `::ditto_error_message` function.
 */
int32_t
/* fn */ ditto_document_update (
    CDocument_t * document,
    slice_ref_uint8_t cbor);

/** \brief
 *  `&'lt [T]` but with a guaranteed `#[repr(C)]` layout.
 *
 *  # C layout (for some given type T)
 *
 *  ```c
 *  typedef struct {
 *  // Cannot be NULL
 *  T * ptr;
 *  size_t len;
 *  } slice_T;
 *  ```
 *
 *  # Nullable pointer?
 *
 *  If you want to support the above typedef, but where the `ptr` field is
 *  allowed to be `NULL` (with the contents of `len` then being undefined)
 *  use the `Option< slice_ptr<_> >` type.
 */
typedef struct slice_ref_CDocument_ptr {
    /** \brief
     *  Pointer to the first element (if any).
     */
    CDocument_t * const * ptr;

    /** \brief
     *  Element count
     */
    size_t len;
} slice_ref_CDocument_ptr_t;

/** <No documentation available> */
typedef struct U64Result {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    uint64_t u64;
} U64Result_t;

/** <No documentation available> */
U64Result_t
/* fn */ ditto_documents_hash (
    slice_ref_CDocument_ptr_t documents);

/** <No documentation available> */
BoxedCharPtrResult_t
/* fn */ ditto_documents_hash_mnemonic (
    slice_ref_CDocument_ptr_t documents);

/** \brief
 *  Retrieves last thread-local error message (used by some synchronous APIs)
 *  and removes it. Subsequent call to this function (if nothing else has
 *  happened) will always return `NULL`.
 *
 *  Returns `NULL` if there was no error. A non-null result MUST be freed using
 *  `ditto_c_string_free`.
 */
char *
/* fn */ ditto_error_message (void);

/** <No documentation available> */
typedef struct CIdentityConfig CIdentityConfig_t;

/** \brief
 *  Whether or not history tracking is enabled.
 */
typedef enum HistoryTracking {
    /** \brief
     *  History tracking is enabled.
     */
    HISTORY_TRACKING_ENABLED,
    /** \brief
     *  History tracking is disabled.
     */
    HISTORY_TRACKING_DISABLED,
} HistoryTracking_t;

/** \brief
 *  Same as `ditto_make()`, only takes an additional `passphrase` and an out
 *  `error_code` parameter.
 *
 *  Returns the Ditto pointer on success. On failure, returns `NULL` and sets the
 *  out `error_code` parameter (1 or 2 possible here, plus IO errors).
 */
CDitto_t *
/* fn */ ditto_experimental_make_with_passphrase (
    char const * working_dir,
    CIdentityConfig_t * identity_config,
    HistoryTracking_t history_tracking,
    char const * passphrase,
    DittoErrorCode_t * error_code);

/** \brief
 *  Frees the `Ditto` object.
 *
 *  It is expected that `ditto_shutdown` will have been called before this is called. However, if it
 *  hasn't been called then it will be called here, inline, to ensure an orderly shutdown process.
 */
void
/* fn */ ditto_free (
    CDitto_t * ditto);

/** \brief
 *  A shared read-only reference to an existing Attachment.
 */
typedef struct AttachmentHandle AttachmentHandle_t;

/** <No documentation available> */
void
/* fn */ ditto_free_attachment_handle (
    AttachmentHandle_t * handle);

/** \brief
 *  [`Box`][`rust::Box`]`<[T]>` (fat pointer to a slice),
 *  but with a guaranteed `#[repr(C)]` layout.
 *
 *  # C layout (for some given type T)
 *
 *  ```c
 *  typedef struct {
 *  // Cannot be NULL
 *  T * ptr;
 *  size_t len;
 *  } slice_T;
 *  ```
 *
 *  # Nullable pointer?
 *
 *  If you want to support the above typedef, but where the `ptr` field is
 *  allowed to be `NULL` (with the contents of `len` then being undefined)
 *  use the `Option< slice_ptr<_> >` type.
 */
typedef struct slice_boxed_size {
    /** \brief
     *  Pointer to the first element (if any).
     */
    size_t * ptr;

    /** \brief
     *  Element count
     */
    size_t len;
} slice_boxed_size_t;

/** \brief
 *  Frees a `slice_box_size_t`, used in `c_cb_params`.
 */
void
/* fn */ ditto_free_indices (
    slice_boxed_size_t indices);

/** <No documentation available> */
typedef struct AttachmentHandleResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    AttachmentHandle_t * handle;
} AttachmentHandleResult_t;

/** <No documentation available> */
AttachmentHandleResult_t
/* fn */ ditto_get_attachment_status (
    CDitto_t * ditto,
    slice_ref_uint8_t id);

/** \brief
 *  Same as [`Vec<T>`][`rust::Vec`], but with guaranteed `#[repr(C)]` layout
 */
typedef struct Vec_char_ptr {
    /** <No documentation available> */
    char * * ptr;

    /** <No documentation available> */
    size_t len;

    /** <No documentation available> */
    size_t cap;
} Vec_char_ptr_t;

/** <No documentation available> */
typedef struct CollectionNamesResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    Vec_char_ptr_t names;
} CollectionNamesResult_t;

/** <No documentation available> */
CollectionNamesResult_t
/* fn */ ditto_get_collection_names (
    CDitto_t const * ditto);

/** <No documentation available> */
typedef struct AttachmentDataResult {
    /** <No documentation available> */
    int8_t status;

    /** <No documentation available> */
    slice_boxed_uint8_t data;
} AttachmentDataResult_t;

/** <No documentation available> */
AttachmentDataResult_t
/* fn */ ditto_get_complete_attachment_data (
    CDitto_t const * ditto,
    AttachmentHandle_t const * handle);

/** <No documentation available> */
char *
/* fn */ ditto_get_complete_attachment_path (
    CDitto_t const * ditto,
    AttachmentHandle_t const * handle);

/** \brief
 *  Returns a human-readable SDK version string, including platform information.
 *  While useful when logging, its exact format or contents ought not to be
 *  relied on.
 *
 *  The returned string must be freed.
 */
char *
/* fn */ ditto_get_sdk_version (void);

/** <No documentation available> */
typedef struct IdentityConfigResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    CIdentityConfig_t * identity_config;
} IdentityConfigResult_t;

/** <No documentation available> */
IdentityConfigResult_t
/* fn */ ditto_identity_config_make_manual (
    char const * manual_identity_str);

/** <No documentation available> */
IdentityConfigResult_t
/* fn */ ditto_identity_config_make_manual_v0 (
    char const * _config_cbor_b64);

/** <No documentation available> */
IdentityConfigResult_t
/* fn */ ditto_identity_config_make_offline_playground (
    char const * app_id,
    uint64_t site_id);

/** <No documentation available> */
IdentityConfigResult_t
/* fn */ ditto_identity_config_make_online_playground (
    char const * app_id,
    char const * shared_token,
    char const * base_url);

/** <No documentation available> */
IdentityConfigResult_t
/* fn */ ditto_identity_config_make_online_with_authentication (
    char const * app_id,
    char const * base_url);

/** <No documentation available> */
IdentityConfigResult_t
/* fn */ ditto_identity_config_make_shared_key (
    char const * app_id,
    char const * key_der_b64,
    uint64_t site_id);

/** <No documentation available> */
typedef enum Platform {
    /** <No documentation available> */
    PLATFORM_WINDOWS,
    /** <No documentation available> */
    PLATFORM_MAC,
    /** <No documentation available> */
    PLATFORM_IOS,
    /** <No documentation available> */
    PLATFORM_TVOS,
    /** <No documentation available> */
    PLATFORM_ANDROID,
    /** <No documentation available> */
    PLATFORM_LINUX,
    /** <No documentation available> */
    PLATFORM_WEB,
    /** <No documentation available> */
    PLATFORM_UNKNOWN,
} Platform_t;

/** <No documentation available> */
typedef enum Language {
    /** <No documentation available> */
    LANGUAGE_SWIFT,
    /** <No documentation available> */
    LANGUAGE_OBJECTIVE_C,
    /** <No documentation available> */
    LANGUAGE_C_PLUS_PLUS,
    /** <No documentation available> */
    LANGUAGE_C_SHARP,
    /** <No documentation available> */
    LANGUAGE_JAVA_SCRIPT,
    /** <No documentation available> */
    LANGUAGE_UNKNOWN,
    /** <No documentation available> */
    LANGUAGE_RUST,
    /** <No documentation available> */
    LANGUAGE_KOTLIN,
    /** <No documentation available> */
    LANGUAGE_JAVA,
    /** <No documentation available> */
    LANGUAGE_FLUTTER,
    /** <No documentation available> */
    LANGUAGE_GO,
} Language_t;

/** <No documentation available> */
void
/* fn */ ditto_init_sdk_version (
    Platform_t platform,
    Language_t language,
    char const * sdk_semver);

typedef struct {
    uint8_t idx[8];
} uint8_8_array_t;

/** \brief
 *  Construct a new Timeseries Event from the following parts:
 *  * `timestamp` - u64 Unix epoch seconds as 8 big endian bytes
 *  * `nanos` - Number of nanoseconds offset into the current second
 *  * `ts_name` - The name of the timeseries
 *  * `cbor` - The cbor content for the event
 *  * `txn` - An optional write transaction. If one is provided then it will not be committed. If
 *  one is not provided then one will be obtained and it will be committed.
 *
 *  Return codes:
 *  * `0` -- success
 *  * `1` -- invalid CBOR
 *  * `2` -- `cbor` is not an object
 *  * `3` -- (js only) concurrent database operation (missing `await`?)
 */
int32_t
/* fn */ ditto_insert_timeseries_event (
    CDitto_t const * ditto,
    uint8_8_array_t timestamp,
    uint32_t nanos,
    char const * ts_name,
    slice_ref_uint8_t cbor,
    CWriteTransaction_t * txn);

/** <No documentation available> */
void
/* fn */ ditto_invalidate_tcp_listeners (
    CDitto_t const * ditto);

/** \brief
 *  Returns `true` if Ditto data at that path is encrypted, otherwise
 *  returns `false`
 */
bool
/* fn */ ditto_is_encrypted (
    CDitto_t const * ditto);

/** \brief
 *  Describes how a live query callback's availability should be treated.
 */
typedef enum LiveQueryAvailability {
    /** \brief
     *  As soon as a transaction is committed that impacts the live query the consumer-provided
     *  callback will be called with the relevant update information. This can be temporarily
     *  delayed if there's a lot of activity leading to the event receivers lagging or if groups of
     *  transactions are coalesced into a single live query update.
     */
    LIVE_QUERY_AVAILABILITY_ALWAYS,
    /** \brief
     *  If `WhenSignalled` is specified then the consumer-provided live query callback will only be
     *  called when there is a transaction committed that impacts the live query *and* the consumer
     *  has signalled that they are ready to receive a new live query event (via the callback).
     */
    LIVE_QUERY_AVAILABILITY_WHEN_SIGNALLED,
} LiveQueryAvailability_t;

/** <No documentation available> */
typedef struct c_cb_params {
    /** \brief
     *  The vec must be freed with `ditto_sparse_vec_documents_free`. The `Document`s contained by
     *  the vec are owned by the recipient of the diff and should be freed independently of the
     *  vec.
     */
    Vec_CDocument_ptr_t documents;

    /** <No documentation available> */
    bool is_initial;

    /** \brief
     *  The vec, if present, must be freed with `ditto_sparse_vec_documents_free`. The `Document`s
     *  contained by the vec are owned by the recipient of the diff and should be freed
     *  independently of the vec.
     */
    Vec_CDocument_ptr_t old_documents;

    /** \brief
     *  Must be freed using `ditto_free_indices`.
     */
    slice_boxed_size_t insertions;

    /** \brief
     *  Must be freed using `ditto_free_indices`.
     */
    slice_boxed_size_t deletions;

    /** \brief
     *  Must be freed using `ditto_free_indices`.
     */
    slice_boxed_size_t updates;

    /** \brief
     *  Must be freed using `ditto_free_indices`.
     */
    slice_boxed_size_t moves;
} c_cb_params_t;

/** <No documentation available> */
typedef struct I64Result {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    int64_t i64;
} I64Result_t;

/** \brief
 *  Convenience function for `ditto_live_query_register`, so as not to require
 *  pre-compiling the query.
 */
I64Result_t
/* fn */ ditto_live_query_register_str (
    CDitto_t const * ditto,
    char const * coll_name,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_by,
    int32_t limit,
    uint32_t offset,
    LiveQueryAvailability_t lq_availability,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*c_cb)(void *, c_cb_params_t));

/** <No documentation available> */
void
/* fn */ ditto_live_query_signal_available_next (
    CDitto_t const * ditto,
    int64_t id);

/** <No documentation available> */
int32_t
/* fn */ ditto_live_query_start (
    CDitto_t const * ditto,
    int64_t legacy_id);

/** <No documentation available> */
void
/* fn */ ditto_live_query_stop (
    CDitto_t const * ditto,
    int64_t legacy_id);

/** <No documentation available> */
typedef enum CLogLevel {
    /** <No documentation available> */
    C_LOG_LEVEL_ERROR = 1,
    /** <No documentation available> */
    C_LOG_LEVEL_WARNING,
    /** <No documentation available> */
    C_LOG_LEVEL_INFO,
    /** <No documentation available> */
    C_LOG_LEVEL_DEBUG,
    /** <No documentation available> */
    C_LOG_LEVEL_VERBOSE,
} CLogLevel_t;

/** \brief
 *  Log function called over FFI such that logging can be grouped into a single
 *  logging mechanism.
 */
void
/* fn */ ditto_log (
    CLogLevel_t level,
    char const * msg);

/** <No documentation available> */
void
/* fn */ ditto_logger_emoji_headings_enabled (
    bool enabled);

/** <No documentation available> */
bool
/* fn */ ditto_logger_emoji_headings_enabled_get (void);

/** <No documentation available> */
void
/* fn */ ditto_logger_enabled (
    bool enabled);

/** <No documentation available> */
bool
/* fn */ ditto_logger_enabled_get (void);

/** \brief
 *  Initializes and registers the global Ditto logger.
 *
 *  This function shouldn't *need* to be called because all of the logging-related FFI calls
 *  *should* start with a call that ensures that the logger is initialized. However, it also
 *  shouldn't hurt to call this.
 */
void
/* fn */ ditto_logger_init (void);

/** <No documentation available> */
void
/* fn */ ditto_logger_minimum_log_level (
    CLogLevel_t log_level);

/** <No documentation available> */
CLogLevel_t
/* fn */ ditto_logger_minimum_log_level_get (void);

/** \brief
 *  Registers a custom logging callback to be called whenever Ditto wants to
 *  issue a log (on _top_ of emitting the log to the console).
 *
 *  Care should be taken not to perform any Ditto operations within this
 *  callback, since those could emit new ditto logs, leading to a recursive
 *  situation. More specifically, this should not be fed `ditto_log`.
 *
 *  A `NULL` may be fed to provide no callback (thus unregistering any
 *  previously registered one).
 */
void
/* fn */ ditto_logger_set_custom_log_cb (
    void (*custom_log_cb)(CLogLevel_t, char *));

/** \brief
 *  Registers a file path where logs will be written to, whenever Ditto wants
 *  to issue a log (on _top_ of emitting the log to the console).
 *
 *  The path, if any, must be within an already existing directory.
 *
 *  A `NULL` may be fed to provide no file (thus unregistering any previously
 *  registered one).
 *
 *  Returns `0` on success, and `-1` otherwise (and the thread local error
 *  message is set accordingly).
 */
int8_t
/* fn */ ditto_logger_set_log_file (
    char const * log_file);

/** \brief
 *  Make a Ditto object as an opaque pointer. The Ditto object creates the Tokio
 *  runtime and starts internal threads. The return value is a raw pointer whose
 *  only use is to supply as an argument to other ditto_* functions. The Ditto
 *  object must be stopped and freed with ditto_free().
 */
CDitto_t *
/* fn */ ditto_make (
    char const * working_dir,
    CIdentityConfig_t * identity_config,
    HistoryTracking_t history_tracking);

/** <No documentation available> */
typedef struct CAttachment {
    /** <No documentation available> */
    slice_boxed_uint8_t id;

    /** <No documentation available> */
    uint64_t len;

    /** <No documentation available> */
    AttachmentHandle_t * handle;
} CAttachment_t;

/** \brief
 *  Creates new Attachment from a blob of bytes link it to the given Document.
 *
 *  Returns following error codes:
 *
 *  * `0` -- no error
 *  * `1` -- an error
 *
 *  In case of a non-zero return value, error message can be retrieved using
 *  `ditto_error_message` function.
 */
uint32_t
/* fn */ ditto_new_attachment_from_bytes (
    CDitto_t const * ditto,
    slice_ref_uint8_t bytes,
    CAttachment_t * out_attachment);

/** \brief
 *  Describes how an attachment file should be handled by our Rust code.
 *
 *  In most cases copying the file will be desirable but with the Android SDK,
 *  for example, we sometimes want to create a tempfile from an InputStream
 *  associated with the attachment file and then move that tempfile rather than
 *  copy it, so as to not make unnecessary copies.
 */
typedef enum AttachmentFileOperation {
    /** <No documentation available> */
    ATTACHMENT_FILE_OPERATION_COPY = 1,
    /** <No documentation available> */
    ATTACHMENT_FILE_OPERATION_MOVE,
} AttachmentFileOperation_t;

/** \brief
 *  Creates new Attachment from a file and link it to the given Document.
 *
 *  Returns following error codes:
 *
 *  * `0` -- no error
 *  * `1` -- an error
 *  * `2` -- file not found
 *  * `3` -- permission denied
 *
 *  In case of a non-zero return value, error message can be retrieved using
 *  `ditto_error_message` function.
 */
uint32_t
/* fn */ ditto_new_attachment_from_file (
    CDitto_t const * ditto,
    char const * source_path,
    AttachmentFileOperation_t file_operation,
    CAttachment_t * out_attachment);

/** \brief
 *  Request data showing who we are connected to in a user-friendly way.
 */
char *
/* fn */ ditto_presence_v3 (
    CDitto_t const * ditto);

/** \brief
 *  `&'lt [T]` but with a guaranteed `#[repr(C)]` layout.
 *
 *  # C layout (for some given type T)
 *
 *  ```c
 *  typedef struct {
 *  // Cannot be NULL
 *  T * ptr;
 *  size_t len;
 *  } slice_T;
 *  ```
 *
 *  # Nullable pointer?
 *
 *  If you want to support the above typedef, but where the `ptr` field is
 *  allowed to be `NULL` (with the contents of `len` then being undefined)
 *  use the `Option< slice_ptr<_> >` type.
 */
typedef struct slice_ref_char_const_ptr {
    /** \brief
     *  Pointer to the first element (if any).
     */
    char const * const * ptr;

    /** \brief
     *  Element count
     */
    size_t len;
} slice_ref_char_const_ptr_t;

/** <No documentation available> */
U64Result_t
/* fn */ ditto_queries_hash (
    CDitto_t const * ditto,
    slice_ref_char_const_ptr_t coll_names,
    slice_ref_char_const_ptr_t queries);

/** <No documentation available> */
BoxedCharPtrResult_t
/* fn */ ditto_queries_hash_mnemonic (
    CDitto_t const * ditto,
    slice_ref_char_const_ptr_t coll_names,
    slice_ref_char_const_ptr_t queries);

/** <No documentation available> */
typedef struct CReadTransactionResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    CReadTransaction_t * txn;
} CReadTransactionResult_t;

/** <No documentation available> */
CReadTransactionResult_t
/* fn */ ditto_read_transaction (
    CDitto_t const * ditto);

/** <No documentation available> */
void
/* fn */ ditto_read_transaction_free (
    CReadTransaction_t * transaction);

/** \brief
 *  Guard for a specific disk usage callback; drop to "unregister" the callback.
 */
typedef struct DiskUsageObserver DiskUsageObserver_t;

/** \brief
 *  Register a function that will be called every time
 *  the given path directory or file is updated.
 *  Return a handle that should be given to ditto_release_disk_usage_callback
 *  to drop the callback
 */
DiskUsageObserver_t *
/* fn */ ditto_register_disk_usage_callback (
    CDitto_t const * ditto,
    FsComponent_t component,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*c_cb)(void *, slice_ref_uint8_t));

/** \brief
 *  Register a function that will be called every time the connection state
 *  of remote peers changes.
 */
void
/* fn */ ditto_register_presence_callback_v3 (
    CDitto_t const * ditto,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*c_cb)(void *, char const *));

/** \brief
 *  Register a function that will be called every time the connection state
 *  of remote peers changes.
 */
void
/* fn */ ditto_register_presence_callback_v3_owned (
    CDitto_t const * ditto,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*c_cb)(void *, char *));

/** \brief
 *  User-friendly categories describing where condition events arose
 */
typedef enum ConditionSource {
    /** <No documentation available> */
    CONDITION_SOURCE_BLUETOOTH,
    /** <No documentation available> */
    CONDITION_SOURCE_TCP,
    /** <No documentation available> */
    CONDITION_SOURCE_AWDL,
    /** <No documentation available> */
    CONDITION_SOURCE_MDNS,
    /** <No documentation available> */
    CONDITION_SOURCE_WIFI_AWARE,
} ConditionSource_t;

/** \brief
 *  Register a function that will be called every time a transport changes
 *  condition.
 *
 *  This should drive UI indicators to indicate overall connectivity via methods
 *  such as BLE, WiFi, or an internet-based server on a dedicated
 *  WsConnectTransport.
 */
void
/* fn */ ditto_register_transport_condition_changed_callback (
    CDitto_t const * ditto,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*c_cb)(void *, ConditionSource_t, TransportCondition_t));

/** \brief
 *  Release the disk usage observer obtained from `ditto_register_disk_usage_callback`
 */
void
/* fn */ ditto_release_disk_usage_callback (
    DiskUsageObserver_t * _handle);

/** <No documentation available> */
int32_t
/* fn */ ditto_remove_subscription (
    CDitto_t const * ditto,
    char const * collection,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_by,
    int32_t limit,
    uint32_t offset);

/** <No documentation available> */
typedef struct CancelTokenResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    int64_t cancel_token;
} CancelTokenResult_t;

/** \brief
 *  Register a new callback to resolve the attachment.
 *
 *  The callback status could be:
 *  * `0` -- complete, with a handle that can be used in ditto_get_complete_attachment_path
 *  * `1` -- progress, with additional info about bytes downloaded and total bytes to download
 *  * `2` -- deleted, as the attachment ceased to exist in the doc database
 *
 *  A cancel token with value `0` represents nil/invalid. This means either an error
 *  occured, or the token has already been fetched or deleted. Note that in this case
 *  the `on_complete_cb` and `on_deleted_cb` callbacks _may_ be called synchronously
 *  even before this function completes.
 *
 *  Returns following error codes:
 *
 *  * `0` -- no error
 *  * `1` -- an error
 *  * `2` -- invalid id
 *  * `3` -- attachment not found
 *
 *  In case of a non-zero status code, error message can be retrieved using
 *  `ditto_error_message` function.
 */
CancelTokenResult_t
/* fn */ ditto_resolve_attachment (
    CDitto_t const * ditto,
    slice_ref_uint8_t id,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*on_complete_cb)(void *, AttachmentHandle_t *),
    void (*on_progress_cb)(void *, uint64_t, uint64_t),
    void (*on_deleted_cb)(void *));

/** <No documentation available> */
uint32_t
/* fn */ ditto_run_garbage_collection (
    CDitto_t const * ditto);

/** <No documentation available> */
bool
/* fn */ ditto_sdk_transports_android_is_inited (void);

/** <No documentation available> */
char *
/* fn */ ditto_sdk_transports_android_missing_permissions (void);

/** <No documentation available> */
void *
/* fn */ ditto_sdk_transports_android_missing_permissions_jni_array (void);

/** <No documentation available> */
void
/* fn */ ditto_sdk_transports_android_shutdown (void);

/** <No documentation available> */
typedef enum DittoSdkTransportsError {
    /** <No documentation available> */
    DITTO_SDK_TRANSPORTS_ERROR_NONE = 0,
    /** <No documentation available> */
    DITTO_SDK_TRANSPORTS_ERROR_GENERIC = 1,
    /** <No documentation available> */
    DITTO_SDK_TRANSPORTS_ERROR_UNAVAILABLE = 2,
    /** <No documentation available> */
    DITTO_SDK_TRANSPORTS_ERROR_MISSING_BLUETOOTH_INFO_PLIST_ENTRY = 3,
    /** <No documentation available> */
    DITTO_SDK_TRANSPORTS_ERROR_MISSING_BLUETOOTH_U_I_BACKGROUND_MODES_INFO_PLIST_ENTRY = 4,
} DittoSdkTransportsError_t;

/** <No documentation available> */
char const *
/* fn */ ditto_sdk_transports_error_description (
    DittoSdkTransportsError_t error);

/** \brief
 *  Frees the output of `ditto_sdk_transports_error_new`.
 */
void
/* fn */ ditto_sdk_transports_error_free (
    DittoSdkTransportsError_t * it);

/** \brief
 *  Obtain a fresh heap-allocated pointer to a (dummy) `DittoSdkTransportsError`.
 *
 *  This is useful for languages with no access to inline/stack allocations and/or unable
 *  to produce pointers themselves.
 */
DittoSdkTransportsError_t *
/* fn */ ditto_sdk_transports_error_new (void);

/** \brief
 *  Obtain the value of a pointer to `DittoSdkTransportsError`
 */
DittoSdkTransportsError_t
/* fn */ ditto_sdk_transports_error_value (
    DittoSdkTransportsError_t const * it);

/** <No documentation available> */
bool
/* fn */ ditto_sdk_transports_init (
    DittoSdkTransportsError_t * out_error);

/** \brief
 *  Must be called from the main thread, before `ditto_sdk_transports_init`.
 *  Calling this from a background thread can result in "Error finding class live/ditto/...".
 *  This is because the class loader for that thread may be the system one,
 *  so attempting to find app-specific classes will fail.
 *  More info at: <https://developer.android.com/training/articles/perf-jni#faq:-why-didnt-findclass-find-my-class>
 */
bool
/* fn */ ditto_sdk_transports_set_android_context (
    void * env,
    void * context);

/** <No documentation available> */
char *
/* fn */ ditto_set_device_name (
    CDitto_t const * ditto,
    char const * device_name);

/** \brief
 *  Shut down Ditto.
 *
 *  All of the `Peer`'s subsystems are told to shut down, which includes, but is not limited to, the
 *  following happening:
 *  - all advertisers shut down
 *  - all servers stopped
 *  - all TCP listeners stopped
 *  - outbound replication stopped
 *
 *  All of the live queries associated with the Ditto instance are also stopped. Any file lock
 *  handles are dropped once any long-running tasks have had a chance to complete.
 */
void
/* fn */ ditto_shutdown (
    CDitto_t const * ditto);

/** \brief
 *  Indicates whether small peer info feature is currently enabled.
 *
 *  `true` if enabled, and `false` if currently disabled. Small peer info
 *  consists of information scraped into a system collection at repeated
 *  interval.
 *
 *  Note: whether the background ingestion process is enabled or not is a
 *  separate decision to whether this information is allowed to sync to other
 *  peers (including the big peer). This is controlled by [`SyncScope`]s. For
 *  the FFI function to get the current sync scope, see
 *  [`ditto_small_peer_info_get_sync_scope`]. By default, the small peer info
 *  document will sync to the big peer.
 *
 *  [`SyncScope`]: DittoSmallPeerInfoSyncScope
 */
bool
/* fn */ ditto_small_peer_info_get_is_enabled (
    CDitto_t const * ditto);

/** \brief
 *  Gets the JSON metadata being used in the small peer info document.
 *
 *  The metadata is free-form, user-provided JSON data that is inserted into
 *  the small peer info system doc at each collection interval. The data has no
 *  schema so it is returned as a c_string. We validated the incoming data with
 *  our constraints, and we do not modify this data, so the same constraints
 *  hold. The validation constraints are:
 *  1. The size of the metadata does not exceed [`SMALL_PEER_INFO_METADATA_SIZE_BYTES_MAX`]
 *  2. The metadata can be parsed as a JSON string and its max depth does not exceed
 *  [`SMALL_PEER_INFO_METADATA_DEPTH_MAX`]
 *  3. The metadata represents a JSON object that can be deserialized into a Map<String, Value>
 *
 *  An empty JSON object string is returned if the data has not been set.
 *
 *  This does not return the metadata from persistent storage. It only returns
 *  the data that has been set to be used by the collector
 *  (via [`ditto_small_peer_info_set_metadata`]) at each collector
 */
char *
/* fn */ ditto_small_peer_info_get_metadata (
    CDitto_t const * ditto);

/** \brief
 *  Which peers to replicate the `__small_peer_info` collection to.
 *
 *  The syncing behavior is dictated by internal [`SyncScope`]s.
 *
 *  By default, the small peer info will sync with the big peer, as dictated by
 *  the default `BigPeerOnly` scope.
 *
 *  NOTE: Currently SDKs can only set [`BigPeerOnly`] or [`LocalPeerOnly`] sync
 *  scopes. [`AllPeers`] and [`SmallPeersOnly`] sync scopes are currently
 *  unsupported. Support for `AllPeers` and `SmallPeersOnly` will be added in
 *  the future, but for that we will need an API for users to subscribe to the
 *  small peer info of other peers.
 *
 *  [`SyncScope`]: ::ditto_store::sync_scope::SyncScope
 *  [`BigPeerOnly`]: ::ditto_store::sync_scope::SyncScope::BigPeerOnly
 *  [`LocalPeerOnly`]: ::ditto_store::sync_scope::SyncScope::LocalPeerOnly
 *  [`AllPeers`]: ::ditto_store::sync_scope::SyncScope::AllPeers
 *  [`SmallPeersOnly`]: ::ditto_store::sync_scope::SyncScope::SmallPeersOnly
 */
typedef enum DittoSmallPeerInfoSyncScope {
    /** <No documentation available> */
    DITTO_SMALL_PEER_INFO_SYNC_SCOPE_BIG_PEER_ONLY,
    /** <No documentation available> */
    DITTO_SMALL_PEER_INFO_SYNC_SCOPE_LOCAL_PEER_ONLY,
} DittoSmallPeerInfoSyncScope_t;

/** \brief
 *  Gets the sync scope for the Small Peer Info collection.
 *
 *  A collection's [SyncScope] determines which "kind" of peers it will
 *  replicate to. The collection does not need to exist locally for this
 *  function to succeed. If no custom sync scope has been set or if the
 *  collection does not exist, the returned scope will be the default
 *  [`LocalPeerOnly`]. Currently, only [`BigPeerOnly`] and [`LocalPeerOnly`] are
 *  supported for small peer info; see [`DittoSmallPeerInfoSyncScope`] for
 *  details.
 *
 *  # Return Values
 *
 *  - Always returns a sync scope - either the custom override set by the user, or the default
 *  scope.
 *
 *  The function currently has no error conditions.
 *
 *  [`SyncScope`]: DittoSmallPeerInfoSyncScope
 *  [`BigPeerOnly`]: DittoSmallPeerInfoSyncScope::BigPeerOnly
 *  [`LocalPeerOnly`]: DittoSmallPeerInfoSyncScope::LocalPeerOnly
 */
DittoSmallPeerInfoSyncScope_t
/* fn */ ditto_small_peer_info_get_sync_scope (
    CDitto_t const * ditto);

/** \brief
 *  Enables or disables the small peer info feature.
 *
 *  Small peer info consists of information scraped into a system collection at
 *  repeated intervals.
 *
 *  Note: whether the background ingestion process is enabled or not is a
 *  separate decision to whether this information is allowed to sync to other
 *  peers (including the big peer). This is controlled by [`SyncScope`]s. For
 *  the FFI function to set sync scopes, see
 *  [`ditto_small_peer_info_set_sync_scope`]. By default, the small peer info
 *  document will sync to the big peer.
 *
 *  [`SyncScope`]: DittoSmallPeerInfoSyncScope
 */
void
/* fn */ ditto_small_peer_info_set_enabled (
    CDitto_t const * ditto,
    bool set_enabled);

/** \brief
 *  Sets the JSON metadata to be used in the small peer info document.
 *
 *  The metadata is free-form, user-provided JSON data that is inserted into
 *  the small peer info system doc at each collection interval. The data has no
 *  schema and is provided as a char_p, so data validation must be performed
 *  here. We validate:
 *  1. The size of the metadata does not exceed [`SMALL_PEER_INFO_METADATA_SIZE_BYTES_MAX`]
 *  2. The metadata can be parsed as a JSON string and its max depth does not exceed
 *  [`SMALL_PEER_INFO_METADATA_DEPTH_MAX`]
 *  3. The metadata represents a JSON object that can be deserialized into a Map<String, Value>
 *
 *  # Return Values
 *
 *  - Returns `0` if the input passes validation and is successfully set to be
 *  used in the small peer info document.
 *  - Returns `-1` in case the observability subsystem is unavailable (which
 *  should never be the case for the small peer).
 *  - Returns `1` if the amount of data is too large according to our
 *  self-imposed limits.
 *  - Returns `2` if the amount of JSON data is too nested according to our
 *  self-imposed limits, or if the data cannot be parsed to determine the depth.
 *  - Returns `3` if the data cannot be parsed as a Map<String, Value>
 */
int32_t
/* fn */ ditto_small_peer_info_set_metadata (
    CDitto_t const * ditto,
    char const * metadata);

/** \brief
 *  Set the sync scope for the Small Peer Info collection.
 *
 *  A collection's [SyncScope] determines which "kind" of peers it will
 *  replicate to. This function can be used even if the Small Peer Info
 *  collection does not yet exist. Currently, only [`BigPeerOnly`] and
 *  [`LocalPeerOnly`] sync scopes are supported for small peer info; see
 *  [`DittoSmallPeerInfoSyncScope`] for details.
 *
 *  The function currently has no error conditions.
 *
 *  [`SyncScope`]: DittoSmallPeerInfoSyncScope
 *  [`BigPeerOnly`]: DittoSmallPeerInfoSyncScope::BigPeerOnly
 *  [`LocalPeerOnly`]: DittoSmallPeerInfoSyncScope::LocalPeerOnly
 */
void
/* fn */ ditto_small_peer_info_set_sync_scope (
    CDitto_t const * ditto,
    DittoSmallPeerInfoSyncScope_t scope);

/** \brief
 *  Allows you to free the vector without dropping the Documents
 */
void
/* fn */ ditto_sparse_vec_documents_free (
    Vec_CDocument_ptr_t docs);

/** <No documentation available> */
void
/* fn */ ditto_transports_ble_advertisement_heard (
    TransportHandle_BlePlatformEvent_t const * handle,
    uint8_16_array_t const * peripheral_uuid,
    slice_ref_uint8_t manufacturer_data,
    bool manufacturer_data_includes_id,
    slice_ref_uint8_t name,
    float rssi);

/** \brief
 *  Request bulk status information about the transports. Intended mostly for
 *  statistical or debugging purposes.
 */
char *
/* fn */ ditto_transports_diagnostics (
    CDitto_t const * ditto);

/** \brief
 *  The whole point
 */
int32_t
/* fn */ ditto_unregister_and_free_legacy_subscription (
    CDitto_t const * ditto,
    LegacySubscriptionHandle_t * handle);

/** <No documentation available> */
uint32_t
/* fn */ ditto_validate_document_id (
    slice_ref_uint8_t cbor,
    slice_boxed_uint8_t * out_cbor);

/** <No documentation available> */
void
/* fn */ ditto_vec_char_ptr_free (
    Vec_char_ptr_t char_p);

/** <No documentation available> */
void
/* fn */ ditto_vec_slice_boxed_uint8_t_free (
    Vec_slice_boxed_uint8_t slice_boxed);

/** <No documentation available> */
typedef enum LicenseVerificationResult {
    /** <No documentation available> */
    LICENSE_VERIFICATION_RESULT_LICENSE_OK = 0,
    /** <No documentation available> */
    LICENSE_VERIFICATION_RESULT_VERIFICATION_FAILED = -1,
    /** <No documentation available> */
    LICENSE_VERIFICATION_RESULT_LICENSE_EXPIRED = -2,
    /** <No documentation available> */
    LICENSE_VERIFICATION_RESULT_UNSUPPORTED_FUTURE_VERSION = -3,
} LicenseVerificationResult_t;

/** \brief
 *  Legacy version of `dittoffi_ditto_set_offline_only_license_token_throws`.
 *
 *  Verify a base64 encoded license string
 *
 *  # Parameters
 *  - `ditto`: The Ditto instance to activate.
 *  - `license`: A base64 encoded license string. This should be the output of
 *  `ditto_licenser::license_mgr::generate()`.
 *  - `out_error_msg`: An optional error message out parameter which will be written to if the
 *  license verification. This error message is simplified and appropriate to show directly to an
 *  SDK user.
 */
LicenseVerificationResult_t
/* fn */ ditto_verify_license (
    CDitto_t const * ditto,
    char const * license,
    char * * out_err_msg);

/** \brief
 *  The platform tells Rust that it should go offline.
 */
void
/* fn */ ditto_wifi_aware_client_go_offline_request (
    TransportHandle_WifiAwarePlatformEvent_t const * handle);

/** \brief
 *  The platform tells Rust that it should go online (because the platform has attached to the WiFi
 *  Aware session)
 */
void
/* fn */ ditto_wifi_aware_client_go_online_request (
    TransportHandle_WifiAwarePlatformEvent_t const * handle);

/** \brief
 *  The platform advises Rust that we have resolved a peer's hostname and port
 */
void
/* fn */ ditto_wifi_aware_client_network_did_create (
    TransportHandle_WifiAwarePlatformEvent_t const * handle,
    char const * announce_string,
    uint32_t scope_id,
    char const * peer_host_address,
    uint16_t port,
    int32_t protocol);

/** \brief
 *  The platform advises Rust that a peer has been identified.
 */
void
/* fn */ ditto_wifi_aware_client_peer_appeared (
    TransportHandle_WifiAwarePlatformEvent_t const * handle,
    char const * announce_string);

/** \brief
 *  The platform advises Rust that we failed to resolve a peer's hostname and
 *  port
 */
void
/* fn */ ditto_wifi_aware_client_peer_did_not_connect (
    TransportHandle_WifiAwarePlatformEvent_t const * handle,
    char const * announce_string);

/** \brief
 *  The platform advises Rust that a peer's service has disappeared from WifiAware.
 */
void
/* fn */ ditto_wifi_aware_client_peer_disappeared (
    TransportHandle_WifiAwarePlatformEvent_t const * handle,
    char const * announce_string);

/** \brief
 *  The platform advises Rust that the status of searching for services has
 *  changed.
 */
void
/* fn */ ditto_wifi_aware_client_scanning_state_changed (
    TransportHandle_WifiAwarePlatformEvent_t const * handle,
    OnlineState_t state,
    TransportCondition_t condition);

/** \brief
 *  The platform advises Rust that the status of publishing our service has
 *  changed.
 */
void
/* fn */ ditto_wifi_aware_server_advertising_state_changed (
    TransportHandle_WifiAwarePlatformEvent_t const * handle,
    OnlineState_t state,
    TransportCondition_t condition);

/** \brief
 *  The platform tells Rust that it should go offline.
 */
void
/* fn */ ditto_wifi_aware_server_go_offline_request (
    TransportHandle_WifiAwarePlatformEvent_t const * handle);

/** \brief
 *  The platform tells Rust that it should go online (because the platform has attached to the WiFi
 *  Aware session)
 */
void
/* fn */ ditto_wifi_aware_server_go_online_request (
    TransportHandle_WifiAwarePlatformEvent_t const * handle);

/** \brief
 *  The platform tells Rust that a WiFi Aware network has been added
 */
void
/* fn */ ditto_wifi_aware_server_network_scope_id_added (
    TransportHandle_WifiAwarePlatformEvent_t const * handle,
    uint32_t scope_id);

/** \brief
 *  The platform tells Rust that a WiFi Aware network has been removed
 */
void
/* fn */ ditto_wifi_aware_server_network_scope_id_removed (
    TransportHandle_WifiAwarePlatformEvent_t const * handle,
    uint32_t scope_id);

/** \brief
 *  The SDK requests to drop its handle to the WifiAware transport
 *
 *  At some point dropping this events channel will effectively shut down and
 *  remove the Transport. At time of writing, the Transport is still owned
 *  within Peer.
 */
void
/* fn */ ditto_wifi_aware_transport_free_handle (
    TransportHandle_WifiAwarePlatformEvent_t * handle);

/** <No documentation available> */
typedef struct CWriteTransactionResult {
    /** <No documentation available> */
    int32_t status_code;

    /** <No documentation available> */
    CWriteTransaction_t * txn;
} CWriteTransactionResult_t;

/** <No documentation available> */
CWriteTransactionResult_t
/* fn */ ditto_write_transaction (
    CDitto_t const * ditto,
    char const * log_hint);

/** \brief
 *  Sets some arbitrary metadata on a write transaction.
 *
 *  This is currently only useful and relevant if history tracking is enabled in
 *  the store that the write transaction relates to. If history tracking is
 *  enabled and metadata is set on a write transaction then the document
 *  inserted into the `__history` collection will have (at least) the provided
 *  metadata stored under the `meta` key of the document.
 *
 *  Return codes:
 *
 *  * `0` -- success
 *  * `1` -- invalid metadata CBOR
 *  * `-1` -- valid metadata CBOR but the CBOR does not represent an object
 *  * `-2` -- [js only] missing `await`s
 */
int32_t
/* fn */ ditto_write_transaction_add_metadata (
    CWriteTransaction_t * transaction,
    slice_ref_uint8_t metadata_cbor);

/** \brief
 *  Commits the given txn.
 *
 *  [js only]: returns -1 on failure, in case of missing `await`s.
 */
int32_t
/* fn */ ditto_write_transaction_commit (
    CDitto_t const * _ditto,
    CWriteTransaction_t * transaction);

/** \brief
 *  Frees the txn handle, *falling back* to a rollback, which requires
 *  `async`-in-drop. Only useful as a safeguard for RAII-with-proper-ownership
 *  languages, _i.e._, the Rust SDK.
 *
 *  For other languages, favor using `ditto_write_transaction_rollback`
 */
void
/* fn */ ditto_write_transaction_free (
    CWriteTransaction_t * transaction);

/** \brief
 *  For SDKs using the batched/scoped write-txn APIs, if an error occurs
 *  mid-operation (_e.g._, customer callback throwing an exception), then the
 *  txn must not be committed, but it ought to be disposed of, _via_ a rollback.
 *
 *  [js only]: returns -1 on failure, in case of missing `await`s.
 */
int32_t
/* fn */ ditto_write_transaction_rollback (
    CDitto_t const * _ditto,
    CWriteTransaction_t * transaction);

/** \brief
 *  Default DittoConfig id value, used by SDKs to synthesize a (rough) DittoConfig after being
 *  built by a legacy constructor.
 */
char const *
/* fn */ dittoffi_DEFAULT_DATABASE_ID (void);

/** \brief
 *  This is not meant to be part of the SDK surface: it's a shared secret that SDKs use when
 *  constructing a "login provider" for development (fka "online playground").
 */
char const *
/* fn */ dittoffi_DITTO_DEVELOPMENT_PROVIDER (void);

/** <No documentation available> */
typedef struct Erased Erased_t;

typedef struct {
    uint8_t idx[15];
} uint8_15_array_t;

/** \brief
 *  A generalization of TCP/UDP's concept of "port", topics identify a Stream's purpose.
 *
 *  Topics MUST be ASCII strings, restricted to the following regex: `^[a-zA-Z0-9_ ]{1,15}$`.
 *
 *  ```
 *  # use std::{convert::TryFrom, str::FromStr};
 *  # use dittolive_ditto_base::datastreams::Topic;
 *  assert!(Topic::new(b"").is_none());
 *  Topic::try_from("a").unwrap();
 *  let _: Topic = "a".parse().unwrap();
 *  Topic::try_from(b"b").unwrap();
 *  Topic::try_from("topic is too long").unwrap_err();
 *  Topic::try_from("invalid.").unwrap_err();
 *  let s = "Hi there";
 *  assert_eq!(Topic::try_from(s).unwrap().as_str(), s);
 *  ```
 */
typedef struct Topic {
    /** <No documentation available> */
    uint8_t len;

    /** <No documentation available> */
    uint8_15_array_t buffer;
} Topic_t;

/** \brief
 *  Requested reliability level for a message to be transmitted to another peer.
 */
/** \remark Has the same ABI as `uint8_t` **/
#ifdef DOXYGEN
typedef
#endif
enum Reliability {
    /** \brief
     *  No guarantees of successful delivery, ordering, or once-only delivery
     */
    RELIABILITY_UNRELIABLE,
    /** \brief
     *  Every message will be delivered in order or else the connection fails
     */
    RELIABILITY_RELIABLE,
}
#ifndef DOXYGEN
; typedef uint8_t
#endif
Reliability_t;

/** <No documentation available> */
typedef struct IAcceptorVTable {
    /** <No documentation available> */
    void (*release_vptr)(Erased_t *);

    /** <No documentation available> */
    Erased_t * (*retain_vptr)(Erased_t const *);

    /** <No documentation available> */
    Topic_t (*topic)(Erased_t const *);

    /** <No documentation available> */
    Reliability_t (*reliability)(Erased_t const *);
} IAcceptorVTable_t;

/** <No documentation available> */
typedef struct VirtualPtr__Erased_ptr_IAcceptorVTable {
    /** <No documentation available> */
    Erased_t * ptr;

    /** <No documentation available> */
    IAcceptorVTable_t vtable;
} VirtualPtr__Erased_ptr_IAcceptorVTable_t;

/** <No documentation available> */
typedef struct Acceptor {
    /** <No documentation available> */
    VirtualPtr__Erased_ptr_IAcceptorVTable_t inner;
} Acceptor_t;

/** <No documentation available> */
void
/* fn */ dittoffi_acceptor_release (
    Acceptor_t * acceptor);

/** <No documentation available> */
Reliability_t
/* fn */ dittoffi_acceptor_reliability (
    Acceptor_t const * acceptor);

/** <No documentation available> */
Acceptor_t
/* fn */ dittoffi_acceptor_retain (
    Acceptor_t const * acceptor);

/** <No documentation available> */
Topic_t
/* fn */ dittoffi_acceptor_topic (
    Acceptor_t const * acceptor);

/** \brief
 *  Communicate to the allocation tracking machinery that we want allocations to start being
 *  tracked.
 *
 *  In practice, all this means is that the allocation tracker will reset to a default state.
 *
 *  If the `alloc-tracking` feature is not enabled then this is a no-op.
 */
void
/* fn */ dittoffi_alloc_tracking_start (void);

/** \brief
 *  Compare current allocations to an empty (default) snapshot and return any leaks as a string.
 *
 *  Returns `None` if no leaks detected.
 *
 *  If the `alloc-tracking` feature is not enabled then this is (essentially) a no-op.
 */
char *
/* fn */ dittoffi_alloc_tracking_stop (void);

/** <No documentation available> */
void
/* fn */ dittoffi_authentication_register_local_server_backend (
    CDitto_t const * ditto,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*auth_cb)(void *, CAuthServerAuthRequest_t *, slice_ref_uint8_t),
    void (*refresh_cb)(void *, CAuthServerRefreshRequest_t *, slice_ref_uint8_t));

/** <No documentation available> */
typedef struct dittoffi_authentication_status dittoffi_authentication_status_t;

/** \brief
 *  Dispose of the auth status.
 */
void
/* fn */ dittoffi_authentication_status_free (
    dittoffi_authentication_status_t * __arg_0);

/** \brief
 *  Extract the authenticated state.
 */
bool
/* fn */ dittoffi_authentication_status_is_authenticated (
    dittoffi_authentication_status_t const * auth_status);

/** \brief
 *  Extract the user ID.
 */
char *
/* fn */ dittoffi_authentication_status_user_id (
    dittoffi_authentication_status_t const * auth_status);

/** \brief
 *  To be used when base64 encoding or decoding.
 *
 *  When encoding, specifies whether to produce padded or unpadded output. When decoding, specifies
 *  whether or not to accept a padded input string.
 */
typedef enum Base64PaddingMode {
    /** <No documentation available> */
    BASE64_PADDING_MODE_PADDED = 1,
    /** <No documentation available> */
    BASE64_PADDING_MODE_UNPADDED,
} Base64PaddingMode_t;

/** \brief
 *  Encodes a slice of bytes as a URL-safe base64 string. The caller can specify whether or not they
 *  want the output to be padded.
 *
 *  The returned string needs to be freed by the caller using `ditto_c_string_free`.
 */
char *
/* fn */ dittoffi_base64_encode (
    slice_ref_uint8_t bytes,
    Base64PaddingMode_t padding_mode);

/** \brief
 *  A safer-ffi friendly equivalent layout to [`ConnectionResult`].
 */
typedef struct BindResult_Layout {
    /** \brief
     *  `true` if accepted, `false` if rejected.
     */
    bool ok;

    /** \brief
     *  Initialized if `accepted` is `true`
     *  if not, must be a valid [`BindError`] instead.
     */
    Acceptor_t acceptor;
} BindResult_Layout_t;

/** <No documentation available> */
bool
/* fn */ dittoffi_bind_result_is_ok (
    BindResult_Layout_t const * result);

/** <No documentation available> */
slice_boxed_uint8_t
/* fn */ dittoffi_bind_result_to_cstr (
    BindResult_Layout_t const * result);

/** <No documentation available> */
Acceptor_t
/* fn */ dittoffi_bind_result_unwrap (
    BindResult_Layout_t result);

/** \brief
 *  A slice of bytes optimized for sharing ownership of it and its subslices.
 *
 *  Typically, [`Bytes`] can constructed from `&'static [u8]`, `Arc<[u8]>` or `Arc<T: AsRef<[u8]>>`.
 *
 *  [`Bytes`] can also "inline" small enough slices: that is, if the slice is more than one byte
 *  smaller than [`Bytes`] memory layout (which is 40 bytes on 64bit architectures), it may be store
 *  directly in that memory instead of through indirection.
 */
typedef struct Bytes {
    /** \brief
     *  The start of the slice.
     */
    uint8_t const * start;

    /** \brief
     *  The length of the slice.
     */
    size_t len;

    /** \brief
     *  The owner of the slice, see [`Bytes::from_raw_parts`] for details.
     */
    void const * owner;

    /** \brief
     *  Named after the field often stored in it, but without actual semantics,
     *  `capacity` is essentially just addtional memory for `owner` which may sometimes
     *  require 2 words to be stored without reallocating. See [`Bytes::from_raw_parts`] for
     *  details.
     */
    size_t capacity;

    /** \brief
     *  If properly aligned (i.e. least significant bit unset), a pointer to an instance of
     *  [`BytesVt`].
     *
     *  If not, the slice is actually inlined in [`Bytes`]'s memory: the least significant byte of
     *  `vtable` then is `(length << 1) | 1`, and the data starts at the address of this
     *  instance of [`Bytes`].
     */
    uint8_t * vtable;
} Bytes_t;

/** \brief
 *  Converts a `Bytes` object into a slice.
 */
slice_ref_uint8_t
/* fn */ dittoffi_bytes_as_slice (
    Bytes_t const * bytes);

/** \brief
 *  Clones a `Bytes` object.
 */
Bytes_t
/* fn */ dittoffi_bytes_clone (
    Bytes_t const * bytes);

/** \brief
 *  Copies a slice into a `Bytes` object.
 *
 *  todo(p-avital): A `dittoffi_bytes_retain_raw()` function should eventually be added to
 *  minimize copies.
 */
Bytes_t
/* fn */ dittoffi_bytes_copied_from_slice (
    slice_ref_uint8_t slice);

/** \brief
 *  Takes a [`c_slice::Box<u8>`] and wraps it in a [`repr_c::Box`].
 *
 *  This is exposed for the Flutter SDK, which has the following requirements:
 *  - We need to support "views" into bytes owned by core (there is no optimized `memcpy`, so
 *  copying is very slow).
 *  - To expose a view, we need to attach a finalizer to clean up memory when GC-able (there is no
 *  "try-with-resources"-style API, and Flutter developers are not used to manual memory
 *  management).
 *  - Flutter's mechanism for native-backed buffers expects that the object passed to `*_free` is
 *  pointer-sized (as libc's `free` expects), but in Rust, we need to reconstruct a `Box<[u8]>` in
 *  order to free it, which requires the length. Given `c_slice::Box<u8>` is approximately a `(*mut
 *  u8, usize)`, it's not compatible with these APIs.
 *
 *  Therefore, a quick solution is to just heap allocate again, so we end up with "a pointer to a
 *  struct which contains a pointer/length pair to the actual bytes". Now we have something
 *  pointer-sized, and can free it automatically. Yay :)
 *
 *  Freed by [`dittoffi_bytes_double_boxed_byte_slice_free`].
 */
slice_boxed_uint8_t *
/* fn */ dittoffi_bytes_double_box_byte_slice (
    slice_boxed_uint8_t slice);

/** \brief
 *  Free function for objects created via [`dittoffi_bytes_double_box_byte_slice`]
 */
void
/* fn */ dittoffi_bytes_double_boxed_byte_slice_free (
    slice_boxed_uint8_t * boxed);

/** \brief
 *  Destroys a `Bytes` object.
 *
 *  Because `Bytes` and `Option<Bytes>` have the same memory layout, this function can be used
 *  to destroy either type.
 *
 *  Note that this function does not attempt to free the `bytes` pointer.
 */
void
/* fn */ dittoffi_bytes_drop (
    Bytes_t * bytes);

/** \brief
 *  Constructs a `None` variant of `Option<Bytes>`.
 */
Bytes_t
/* fn */ dittoffi_bytes_option_none (void);

/** \brief
 *  Wraps a `Bytes` object into an option. Because these types have the same memory layout,
 *  this is actually a no-op.
 */
Bytes_t
/* fn */ dittoffi_bytes_option_some (
    Bytes_t bytes);

/** \brief
 *  The ditto error type, opaque.
 */
typedef struct dittoffi_error dittoffi_error_t;

/** <No documentation available> */
typedef struct dittoffi_result_slice_boxed_uint8 {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    slice_boxed_uint8_t success;
} dittoffi_result_slice_boxed_uint8_t;

/** \brief
 *  Round-trip deserializes and serializes a CBOR object.
 *
 *  Warning: This is intended as a utility for SDKs to use in tests, to validate their own to/from
 *  CBOR implementations. It should not be used in production code.
 *
 *  It takes a CBOR blob `bytes`, as well as a string `ty` identifying the type it should be
 *  intepreted as. The valid values for `ty` are:
 *  - `"transport_config"`
 *  - `"ditto_config"`
 *
 *  In the success case, it returns CBOR bytes containing the object passed in.
 *
 *  It can fail in two possible ways:
 *  - by returning `FfiError::Internal` if the `ty` string doesn't correspond to a known type
 *  - by returning `FfiError::ValidationInvalidCbor` if a CBOR decoding error is encountered
 *
 *  [encoded cbor data item]: https://datatracker.ietf.org/doc/html/rfc8949#name-encoded-cbor-data-item
 */
dittoffi_result_slice_boxed_uint8_t
/* fn */ dittoffi_cbor_round_trip (
    char const * ty,
    slice_ref_uint8_t bytes);

/** <No documentation available> */
BoolResult_t
/* fn */ dittoffi_check_doc_cbor_against_provided_cbor (
    slice_ref_uint8_t document_cbor,
    slice_ref_uint8_t provided_cbor);

/** <No documentation available> */
typedef struct IConnectionHandleVTable {
    /** <No documentation available> */
    void (*release_vptr)(Erased_t *);

    /** <No documentation available> */
    Erased_t * (*retain_vptr)(Erased_t const *);

    /** \brief
     *  Attempts to cancel the connection attempt.
     *
     *  If the connection attempt has already succeeded or failed, this does nothing.
     */
    void (*cancel)(Erased_t const *);
} IConnectionHandleVTable_t;

/** <No documentation available> */
typedef struct VirtualPtr__Erased_ptr_IConnectionHandleVTable {
    /** <No documentation available> */
    Erased_t * ptr;

    /** <No documentation available> */
    IConnectionHandleVTable_t vtable;
} VirtualPtr__Erased_ptr_IConnectionHandleVTable_t;

/** \brief
 *  A handle on a connection attempt, that will attempt to cancel said attempt if dropped.
 *
 *  Note that cancelling a connection attempt that has already succeeded will have no effect.
 */
typedef struct ConnectionHandle {
    /** <No documentation available> */
    VirtualPtr__Erased_ptr_IConnectionHandleVTable_t inner;
} ConnectionHandle_t;

/** <No documentation available> */
void
/* fn */ dittoffi_connection_handle_cancel (
    ConnectionHandle_t const * handle);

/** <No documentation available> */
void
/* fn */ dittoffi_connection_handle_release (
    ConnectionHandle_t * handle);

/** <No documentation available> */
ConnectionHandle_t
/* fn */ dittoffi_connection_handle_retain (
    ConnectionHandle_t const * handle);

/** \brief
 *  Opaque type encapsulating the different args provided to the `.on_connecting()`
 *  callback in a future-proof fashion.
 *
 *  This is the lowest-level "wrapped" callback, i.e. the most convenient set of types for
 *  passing across the FFI barrier.
 *
 *  Typically, SDKs will have a wrapping method that does the (de)serialization to/from CBOR
 *  to create a more user-friendly function signature for `connecting_peer`.
 */
typedef struct dittoffi_connection_request dittoffi_connection_request_t;

/** <No documentation available> */
typedef enum dittoffi_connection_request_authorization {
    /** <No documentation available> */
    DITTOFFI_CONNECTION_REQUEST_AUTHORIZATION_DENY,
    /** <No documentation available> */
    DITTOFFI_CONNECTION_REQUEST_AUTHORIZATION_ALLOW,
} dittoffi_connection_request_authorization_t;

/** \brief
 *  Answer/output of the `connection_request_handler`, communicated through the `connection_request`
 *  object.
 *  `true` allows the connection, `false` rejects it.
 */
void
/* fn */ dittoffi_connection_request_authorize (
    dittoffi_connection_request_t const * r,
    dittoffi_connection_request_authorization_t authorized);

/** \brief
 *  A simplified [`ConnectionType`] exposed to the SDKs
 */
typedef enum dittoffi_connection_type {
    /** <No documentation available> */
    DITTOFFI_CONNECTION_TYPE_BLUETOOTH,
    /** <No documentation available> */
    DITTOFFI_CONNECTION_TYPE_ACCESS_POINT,
    /** <No documentation available> */
    DITTOFFI_CONNECTION_TYPE_P2_P_WI_FI,
    /** <No documentation available> */
    DITTOFFI_CONNECTION_TYPE_WEB_SOCKET,
} dittoffi_connection_type_t;

/** \brief
 *  The connection type being used to connect with the connecting peer.
 */
dittoffi_connection_type_t
/* fn */ dittoffi_connection_request_connection_type (
    dittoffi_connection_request_t const * r);

/** <No documentation available> */
void
/* fn */ dittoffi_connection_request_free (
    dittoffi_connection_request_t * __arg_0);

/** \brief
 *  Getter for the `identity_service` as a JSON (string / UTF-8 data).
 */
slice_ref_uint8_t
/* fn */ dittoffi_connection_request_identity_service_metadata_json (
    dittoffi_connection_request_t const * r);

/** \brief
 *  The connecting peer's (pub) key (empty for legacy peers), hex-encoded as a string
 */
char *
/* fn */ dittoffi_connection_request_peer_key_string (
    dittoffi_connection_request_t const * r);

/** \brief
 *  Getter for the `peer_metadata` as a JSON (string / UTF-8 data).
 */
slice_ref_uint8_t
/* fn */ dittoffi_connection_request_peer_metadata_json (
    dittoffi_connection_request_t const * r);

typedef struct {
    void const * idx[2];
} void_const_ptr_2_array_t;

/** \brief
 *  The reason for a connection attempt's failure.
 */
/** \remark Has the same ABI as `uint8_t` **/
#ifdef DOXYGEN
typedef
#endif
enum CancellationError {
    /** \brief
     *  Cancelling the send operation failed.
     */
    CANCELLATION_ERROR_CANCELLATION_FAILED,
}
#ifndef DOXYGEN
; typedef uint8_t
#endif
CancellationError_t;

/** \brief
 *  A safer-ffi friendly equivalent layout to [`CancellationResult`].
 */
typedef struct CancellationResult_Layout {
    /** \brief
     *  `true` if cancelling succeeded, `false` otherwise.
     */
    bool success;

    /** \brief
     *  Initialized iff `accepted` is `true`,
     *  if not, must be a valid [`CancellationError`] instead
     */
    CancellationError_t error_reason;
} CancellationResult_Layout_t;

/** \brief
 *  Indicates the status of a given send operation.
 *
 *  A [`SendHandle`]'s state may become [`Unknown`](SendStatus::Unknown) at any time,
 *  but may never return to another state after that.
 *
 *  Transition details:
 *  - `Pending -> Sent`: Trivial, each state is technically allowed to represent the other.
 *  - `Pending -> Failed`: This likely indicates that the stream has been closed before the message
 *  could be sent. This may be due to a network issue or simply your peer closing the stream on
 *  their end.
 *  - `Pending` -> `Cancelled`: This indicates that the send operation was cancelled, although it
 *  does not guarantee that the peer will never receive the cancelled message.
 */
/** \remark Has the same ABI as `uint8_t` **/
#ifdef DOXYGEN
typedef
#endif
enum SendStatus {
    /** \brief
     *  The send status couldn't be recovered.
     *
     *  Transition to this state may happen from any state (including "final" states),
     *  as the status may stop being tracked.
     */
    SEND_STATUS_UNKNOWN = 0,
    /** \brief
     *  The send operation is still pending.
     *
     *  Note this doesn't guarantee that the message _hasn't_ been sent or acknowledged yet,
     *  just that the handle wasn't able to confirm that either of these states has been
     *  reached.
     */
    SEND_STATUS_PENDING = 1,
    /** \brief
     *  The send operation has been executed, but no acknowledgement has been received by the
     *  handle.
     */
    SEND_STATUS_SENT = 2,
    /** \brief
     *  The send was identified as having failed.
     *
     *  This typically would happen if the target disconnected before reaching one of the other end
     *  states.
     */
    SEND_STATUS_FAILED = 3,
    /** \brief
     *  The send was cancelled.
     *
     *  Note that this does not guarantee that the message won't be delivered, even if it hadn't
     *  been sent yet.
     */
    SEND_STATUS_CANCELLED = 4,
}
#ifndef DOXYGEN
; typedef uint8_t
#endif
SendStatus_t;

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_SendStatus {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, SendStatus_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_SendStatus_t;

/** <No documentation available> */
typedef struct ISendHandleVTable {
    /** <No documentation available> */
    void (*release_vptr)(Erased_t *);

    /** <No documentation available> */
    Erased_t * (*retain_vptr)(Erased_t const *);

    /** \brief
     *  Attempts to cancel the send operation, returning the payload of the message once the
     *  cancellation succeeds.
     *
     *  This cancellation may fail to cancel the operation, even if the message is still in a
     *  send queue.
     *
     *  If a continuation has been passed to `Self::then`, and hasn't been called yet, it _must_ be
     *  called with the current result of `Self::poll`.
     */
    CancellationResult_Layout_t (*cancel)(Erased_t const *);

    /** \brief
     *  Returns the current status of the operation.
     *
     *  Note that consistency isn't guaranteed: calling `poll` after `then` may yield a
     *  different result than that yielded to the continuation. In such a case, the
     *  continuation's argument is considered "canon".
     */
    SendStatus_t (*poll)(Erased_t const *);

    /** \brief
     *  Calls the `callback` when the send status changes.
     *
     *  Previously set callbacks MUST:
     *  - Never be called upon a change in the [`SendStatus`] if `keep_previous == false` once this
     *  method returns.
     *  - Also be called upon a change in the [`SendStatus`] if `keep_previous == true`, without any
     *  call order being specified.
     */
    void (*set_on_change)(Erased_t const *, BoxDynFnMut1_void_SendStatus_t, bool);
} ISendHandleVTable_t;

/** <No documentation available> */
typedef struct VirtualPtr__Erased_ptr_ISendHandleVTable {
    /** <No documentation available> */
    Erased_t * ptr;

    /** <No documentation available> */
    ISendHandleVTable_t vtable;
} VirtualPtr__Erased_ptr_ISendHandleVTable_t;

/** \brief
 *  Identifies whether the stream was closed locally or remotely.
 */
/** \remark Has the same ABI as `uint8_t` **/
#ifdef DOXYGEN
typedef
#endif
enum StreamStatus {
    /** \brief
     *  The stream is open
     */
    STREAM_STATUS_OPEN,
    /** \brief
     *  The stream was closed by the remote peer.
     */
    STREAM_STATUS_CLOSED_BY_REMOTE,
    /** \brief
     *  The stream was closed by the locally.
     */
    STREAM_STATUS_CLOSED_BY_LOCAL,
}
#ifndef DOXYGEN
; typedef uint8_t
#endif
StreamStatus_t;

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_StreamStatus {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, StreamStatus_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_StreamStatus_t;

/** <No documentation available> */
typedef struct IStreamVTable {
    /** <No documentation available> */
    void (*release_vptr)(Erased_t *);

    /** <No documentation available> */
    Erased_t * (*retain_vptr)(Erased_t const *);

    /** \brief
     *  The peer with which the stream is/will be connected.
     */
    void_const_ptr_2_array_t (*peer_pubkey)(Erased_t const *);

    /** \brief
     *  The topic of the stream.
     *
     *  The return value _may_ alias `self`. You can ensure it's fully owned by calling
     *  [`Bytes::upgrade`](safer_ffi::bytes::Bytes::upgrade) which will copy only if necessary.
     */
    Topic_t (*topic)(Erased_t const *);

    /** \brief
     *  Send a payload.
     *
     *  The returned SendHandle can be used to cancel the send (provided it hasn't already been
     *  delivered). `finished` is called once the send is considered complete
     *  (immediately for unreliable streams, upon ACK otherwise). If the send failed
     *  (only allowed for cancelations), the payload
     */
    VirtualPtr__Erased_ptr_ISendHandleVTable_t (*send)(Erased_t const *, Bytes_t);

    /** \brief
     *  Returns the stream's closer if the stream was indeed closed.
     */
    StreamStatus_t (*current_status)(Erased_t const *);

    /** \brief
     *  Adds a `continuation` on the stream's closure.
     *
     *  All continuations added to the stream's closure will be called once it is closed.
     *
     *  The `continuation` is guaranteed to be called if the stream was already closed.
     */
    void (*add_on_close)(Erased_t const *, BoxDynFnMut1_void_StreamStatus_t);

    /** \brief
     *  Returns the maximum size of a payload that can be sent on this stream.
     *
     *  This may be 0 if the stream has been closed.
     *
     *  Note that a stream may receive messages larger than this size.
     */
    size_t (*max_send_size)(Erased_t const *);

    /** \brief
     *  Returns a hash of the candidate's type ID, allowing internal code to identify the candidate
     *  type and downcast it if necessary.
     *
     *  There's never any point in using it outside of Ditto's codebase.
     */
    uint64_t (*type_id)(Erased_t const *);
} IStreamVTable_t;

/** <No documentation available> */
typedef struct VirtualPtr__Erased_ptr_IStreamVTable {
    /** <No documentation available> */
    Erased_t * ptr;

    /** <No documentation available> */
    IStreamVTable_t vtable;
} VirtualPtr__Erased_ptr_IStreamVTable_t;

/** \brief
 *  An open, bidirectional stream.
 */
typedef struct Stream {
    /** <No documentation available> */
    VirtualPtr__Erased_ptr_IStreamVTable_t inner;
} Stream_t;

/** \brief
 *  Simplified for lighter documentation, but the actual impls
 *  range from `Tuple1` up to `Tuple6`.
 */
typedef struct Tuple2_bool_Stream {
    /** <No documentation available> */
    bool _0;

    /** <No documentation available> */
    Stream_t _1;
} Tuple2_bool_Stream_t;

/** \brief
 *  An inbound message.
 *
 *  Inbound messages currently only contain the message's payload, but metadata may be added future
 *  updates.
 */
typedef struct Inbound {
    /** <No documentation available> */
    Bytes_t payload;
} Inbound_t;

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_Inbound {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, Inbound_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_Inbound_t;

/** \brief
 *  Simplified for lighter documentation, but the actual impls
 *  range from `Tuple1` up to `Tuple6`.
 */
typedef struct Tuple2_bool_BoxDynFnMut1_void_Inbound {
    /** <No documentation available> */
    bool _0;

    /** <No documentation available> */
    BoxDynFnMut1_void_Inbound_t _1;
} Tuple2_bool_BoxDynFnMut1_void_Inbound_t;

/** <No documentation available> */
typedef struct IStreamCandidateVTable {
    /** <No documentation available> */
    void (*release_vptr)(Erased_t *);

    /** <No documentation available> */
    Erased_t * (*retain_vptr)(Erased_t const *);

    /** \brief
     *  The peer with which the stream is/will be connected.
     */
    void_const_ptr_2_array_t (*peer_pubkey)(Erased_t const *);

    /** \brief
     *  The topic of the stream.
     *
     *  The return value _may_ alias `self`. You can ensure it's fully owned by calling
     *  [`Bytes::upgrade`](safer_ffi::bytes::Bytes::upgrade) which will copy only if necessary.
     */
    Topic_t (*topic)(Erased_t const *);

    /** \brief
     *  Returns the arguments set by the remote peer when initiating the stream, if any.
     *
     *  Arguments may have been set either through [`IEndpoint::connect`] for the client,
     *  or through [`IStreamCandidate::open`] for the server.
     */
    Bytes_t (*arguments)(Erased_t const *);

    /** \brief
     *  Confirms the stream's opening, setting its optional callback.
     *
     *  Failing to call this before the candidate is destroyed will close the connection.
     *
     *  The `on_recv` callback will be called upon receiving inbound messages.
     *  It is guaranteed to never be called concurrently, and will receive messages in order
     *  if the stream is reliable (unreliable streams don't have an ordering preservation
     *  guarantee).
     *
     *  `arguments` are optional payload sent to the remote peer when accepting the stream, and are
     *  only valid for "server-side" stream candidates, as the "client"'s opportunity to send
     *  arguments is in [`IEndpoint::connect`].
     */
    Tuple2_bool_Stream_t (*open)(Erased_t const *, Tuple2_bool_BoxDynFnMut1_void_Inbound_t, Bytes_t);

    /** \brief
     *  Returns a hash of the candidate's type ID, allowing internal code to identify the candidate
     *  type and downcast it if necessary.
     *
     *  There's never any point in using it outside of Ditto's codebase.
     */
    uint64_t (*type_id)(Erased_t const *);
} IStreamCandidateVTable_t;

/** <No documentation available> */
typedef struct VirtualPtr__Erased_ptr_IStreamCandidateVTable {
    /** <No documentation available> */
    Erased_t * ptr;

    /** <No documentation available> */
    IStreamCandidateVTable_t vtable;
} VirtualPtr__Erased_ptr_IStreamCandidateVTable_t;

/** \brief
 *  Before a [`Stream`] can be fully open, its receive callback must be set through
 *  [`StreamCandidate::open`] or [`StreamCandidate::open_write_only`].
 *
 *  If a [`StreamCandidate`] is dropped before it is fully open, the underlying [`Stream`] will
 *  be closed, notifying the remote peer.
 *
 *  Moreover, an [`Acceptor`] may wait for its yielded [`StreamCandidate`] to be opened before
 *  notifying the connecting peer of its acceptance, preventing the opposing `ConnectionFuture`
 *  from resolving.
 *
 *  Note that `ConnectionBuilder` and `AcceptorBuilder`, which are the only sources of
 *  [`StreamCandidate`]s, both have a `on_receive_factory` method: this method allows you to set a
 *  common policy for [`StreamCandidate::open`]ing the [`Stream`], which is generally more
 *  convenient and may spare you some head-scratching with regard to the above note on
 *  `ConnectionFuture`'s resolution.
 */
typedef struct StreamCandidate {
    /** <No documentation available> */
    VirtualPtr__Erased_ptr_IStreamCandidateVTable_t inner;
} StreamCandidate_t;

/** \brief
 *  A safer-ffi friendly equivalent layout to [`ConnectionResult`].
 */
typedef struct ConnectionResult_Layout {
    /** \brief
     *  `true` if accepted, `false` if rejected.
     */
    bool accepted;

    /** \brief
     *  Initialized if `accepted` is `true`
     *  if not, must be a valid [`ConnectionError`] instead
     */
    StreamCandidate_t stream;
} ConnectionResult_Layout_t;

/** <No documentation available> */
bool
/* fn */ dittoffi_connection_result_is_ok (
    ConnectionResult_Layout_t const * result);

/** <No documentation available> */
slice_boxed_uint8_t
/* fn */ dittoffi_connection_result_to_cstr (
    ConnectionResult_Layout_t const * result);

/** <No documentation available> */
StreamCandidate_t
/* fn */ dittoffi_connection_result_unwrap (
    ConnectionResult_Layout_t result);

/** \brief
 *  Generates 32 random bytes and returns them as a base64 (URL safe and padded) encoded string.
 *
 *  The returned string needs to be freed using `ditto_c_string_free`.
 *
 *  Note: This is currently only being used by the JS SDK. Any other usage of this function is
 *  likely indicative of a deficiency in the API being provided to SDKs.
 */
char *
/* fn */ dittoffi_crypto_generate_secure_random_token (void);

/** \brief
 *  An FFI appropriate, opaque representation of a differ.
 */
typedef struct dittoffi_differ dittoffi_differ_t;

/** \brief
 *  An individual result item from a query result (which holds a list of these items).
 */
typedef struct dittoffi_query_result_item dittoffi_query_result_item_t;

/** \brief
 *  `&'lt [T]` but with a guaranteed `#[repr(C)]` layout.
 *
 *  # C layout (for some given type T)
 *
 *  ```c
 *  typedef struct {
 *  // Cannot be NULL
 *  T * ptr;
 *  size_t len;
 *  } slice_T;
 *  ```
 *
 *  # Nullable pointer?
 *
 *  If you want to support the above typedef, but where the `ptr` field is
 *  allowed to be `NULL` (with the contents of `len` then being undefined)
 *  use the `Option< slice_ptr<_> >` type.
 */
typedef struct slice_ref_dittoffi_query_result_item_ptr {
    /** \brief
     *  Pointer to the first element (if any).
     */
    dittoffi_query_result_item_t * const * ptr;

    /** \brief
     *  Element count
     */
    size_t len;
} slice_ref_dittoffi_query_result_item_ptr_t;

/** <No documentation available> */
typedef slice_boxed_uint8_t dittoffi_cbor_data_t;

/** \brief
 *  Generate a diff between the given items and the differ's current list of items.
 *
 *  The diff is returned as a CBOR serialized object, in the form of an object like this:
 *
 *  ```json
 *  {
 *  "insertions": [0, 1],
 *  "deletions": [2, 3],
 *  "updates": [4, 5],
 *  "moves": [[6, 7], [8, 9]]
 *  }
 *  ```
 *
 *  Note that the `moves` array is an array of arrays, where each inner array is a pair of indices
 *  representing `from` and `to` indices. The `from` index is the first element in the array and the
 *  `to` index is the second element in the array, for each array in the `moves` array.
 */
dittoffi_cbor_data_t
/* fn */ dittoffi_differ_diff (
    dittoffi_differ_t const * differ,
    slice_ref_dittoffi_query_result_item_ptr_t items);

/** \brief
 *  Free the differ.
 */
void
/* fn */ dittoffi_differ_free (
    dittoffi_differ_t * differ);

/** \brief
 *  Returns the identity key path at the given index in the differ's list of identity key paths.
 *
 *  # Safety
 *
 *  The caller must ensure that the index is valid (i.e. less than the count of identity key paths).
 */
char *
/* fn */ dittoffi_differ_identity_key_path_at (
    dittoffi_differ_t const * differ,
    size_t idx);

/** \brief
 *  Returns the number of identity key paths in use by the differ.
 */
size_t
/* fn */ dittoffi_differ_identity_key_path_count (
    dittoffi_differ_t const * differ);

/** \brief
 *  Create a new differ.
 *
 *  This differ will use the default identity key paths list, which is just `["_id"]`. This is the
 *  default because the legacy query builder differ code uses the equivalent to this.
 */
dittoffi_differ_t *
/* fn */ dittoffi_differ_new (void);

/** <No documentation available> */
typedef struct dittoffi_result_dittoffi_differ_ptr {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    dittoffi_differ_t * success;
} dittoffi_result_dittoffi_differ_ptr_t;

/** \brief
 *  Create a new differ using the provided identity key paths.
 */
dittoffi_result_dittoffi_differ_ptr_t
/* fn */ dittoffi_differ_new_with_identity_key_paths_throws (
    slice_ref_char_const_ptr_t identity_key_paths);

/** \brief
 *  Getter for `absolute_persistence_directory`, which is the *actual* data directory used by
 *  Ditto (it will differ from config.persistence_directory when the latter is *relative* or *nil*.)
 *
 *  The resulting string has to be freed with `::ditto_c_string_free`
 */
char *
/* fn */ dittoffi_ditto_absolute_persistence_directory (
    CDitto_t const * ditto);

/** \brief
 *  Internal helper function to do integration testing of stacktrace generation in the SDKs.
 */
char *
/* fn */ dittoffi_ditto_capture_stack_trace_string_internal (void);

/** \brief
 *  Getter for `DittoConfig` serialized as CBOR, according to the DittoConfig.schema.json schema.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_ditto_config (
    CDitto_t const * ditto);

/** \brief
 *  Returns a sensible *default* `DittoConfig` serialized as CBOR, according to the
 *  DittoConfig.schema.json schema.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_ditto_config_default (void);

/** <No documentation available> */
typedef struct dittoffi_result_bool {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    bool success;
} dittoffi_result_bool_t;

/** <No documentation available> */
dittoffi_result_bool_t
/* fn */ dittoffi_ditto_get_system_parameter_bool (
    CDitto_t const * ditto,
    char const * parameter_name);

/** <No documentation available> */
typedef struct dittoffi_result_uint64 {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    uint64_t success;
} dittoffi_result_uint64_t;

/** <No documentation available> */
dittoffi_result_uint64_t
/* fn */ dittoffi_ditto_get_system_parameter_u64 (
    CDitto_t const * ditto,
    char const * parameter_name);

/** \brief
 *  Returns whether or not the Ditto instance has been activated with a valid license token.
 *
 *  When a Ditto instance is using non-online identity types then this will always return `true`.
 */
bool
/* fn */ dittoffi_ditto_is_activated (
    CDitto_t const * ditto);

/** <No documentation available> */
bool
/* fn */ dittoffi_ditto_is_sync_active (
    CDitto_t const * ditto);

/** \brief
 *  Whether or not the default values for parts of a `TransportConfig` that could be
 *  platform-dependent should be determined based on the platform that the SDK is running on.
 *
 *  For example, if `PlatformDependent` is chosen for the `TransportConfigMode`, then the default
 *  value for whether AWDL would be enabled would be based on whether the SDK is running on an Apple
 *  platform. Specifically, if you were running on an iOS device, for example, then AWDL would
 *  default to enabled, but if you were using the .NET SDK running on a Windows machine then AWDL
 *  would default to false.
 *
 *  If `TransportConfigMode::PlatformIndependent` is chosen, then the default value would always be
 *  true (at least in the case of whether or not AWDL is enabled).
 *
 *  This really only exists to cater for the difference in behavior between the JS (and Flutter) and
 *  other SDKs. The JS SDK's default value for platform-specific transports will be determined by
 *  the platform that the JS SDK is running on, whereas the other SDKs will default to the same
 *  value regardless of the platform that they are running on.
 */
typedef enum TransportConfigMode {
    /** <No documentation available> */
    TRANSPORT_CONFIG_MODE_PLATFORM_DEPENDENT,
    /** <No documentation available> */
    TRANSPORT_CONFIG_MODE_PLATFORM_INDEPENDENT,
} TransportConfigMode_t;

/** <No documentation available> */
typedef struct dittoffi_result_CDitto_ptr {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    CDitto_t * success;
} dittoffi_result_CDitto_ptr_t;

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_dittoffi_result_CDitto_ptr {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, dittoffi_result_CDitto_ptr_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_dittoffi_result_CDitto_ptr_t;

/** \brief
 *  Continuation (`repr_c::Box<dyn FnMut(…)>` FFI-safe callback) to be used as
 *  the *completion handler* for conceptually-`async` APIs.
 */
typedef BoxDynFnMut1_void_dittoffi_result_CDitto_ptr_t continuation_dittoffi_result_CDitto_ptr_t;

/** \brief
 *  One of the two supported factory functions / constructors for opening a Ditto instance.
 *
 *  * `config_cbor` - `DittoConfig` serialized as CBOR, according to the DittoConfig.schema.json
 *  schema
 *
 *  * `default_root_directory` - If the config.persistence_directory is nil or relative, this will
 *  be used as the parent of the actual persistence directory.
 *
 *  Nothing interesting happens in this function: it simply calls `Ditto::new` after creating a
 *  `TaskRuntime`.
 *
 *  See: `dittoffi_ditto_open_throws` for a synchronous version.
 */
void
/* fn */ dittoffi_ditto_open_async_throws (
    slice_ref_uint8_t config_cbor,
    TransportConfigMode_t transport_config_mode,
    char const * default_root_directory,
    continuation_dittoffi_result_CDitto_ptr_t continuation);

/** \brief
 *  One of the two supported factory functions / constructors for opening a Ditto instance.
 *
 *  * `config_cbor` - `DittoConfig` serialized as CBOR, according to the DittoConfig.schema.json
 *  schema
 *
 *  * `default_root_directory` - If the config.persistence_directory is nil or relative, this will
 *  be used as the parent of the actual persistence directory.
 *
 *  Nothing interesting happens in this function: it simply calls *and blocks on* `Ditto::new` after
 *  creating a `TaskRuntime`.
 *
 *  See: `dittoffi_ditto_open_async_throws` for an asynchronous version.
 */
dittoffi_result_CDitto_ptr_t
/* fn */ dittoffi_ditto_open_throws (
    slice_ref_uint8_t config_cbor,
    TransportConfigMode_t transport_config_mode,
    char const * default_root_directory);

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_dittoffi_authentication_status_ptr {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, dittoffi_authentication_status_t *);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_dittoffi_authentication_status_ptr_t;

/** <No documentation available> */
typedef BoxDynFnMut1_void_dittoffi_authentication_status_ptr_t dittoffi_authentication_status_handler_t;

/** <No documentation available> */
void
/* fn */ dittoffi_ditto_set_authentication_status_handler (
    CDitto_t const * ditto,
    dittoffi_authentication_status_handler_t handler);

/** \brief
 *  Set whether or not the cloud sync should be enabled for the Ditto instance.
 *
 *  This is a bit of a hack for now. It should only be called once, at the start of a (SDK) Ditto's
 *  instance's lifecycle. Calling this ensures that correct transport configs will be computed when
 *  using the "transports behind core" logic (i.e. using the core-defined logic for ensuring the
 *  correct transports are started/stopped at the correct time).
 *
 *  Eventually this should likely be folded into `TransportConfig` somehow.
 */
void
/* fn */ dittoffi_ditto_set_cloud_sync_enabled (
    CDitto_t const * ditto,
    bool enabled);

/** <No documentation available> */
typedef struct dittoffi_result_void {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;
} dittoffi_result_void_t;

/** \brief
 *  Verify a base64 encoded license string.
 *
 *  # Parameters
 *  - `ditto`: The Ditto instance to activate.
 *  - `license`: A base64 encoded license string. This should be the output of
 *  `ditto_licenser::license_mgr::generate()`.
 */
dittoffi_result_void_t
/* fn */ dittoffi_ditto_set_offline_only_license_token_throws (
    CDitto_t const * ditto,
    char const * license);

/** <No documentation available> */
typedef struct dittoffi_panic dittoffi_panic_t;

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_dittoffi_panic_ptr {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, dittoffi_panic_t *);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_dittoffi_panic_ptr_t;

/** <No documentation available> */
typedef BoxDynFnMut1_void_dittoffi_panic_ptr_t dittoffi_panic_handler_t;

/** \brief
 *  Registers a custom callback/hook to report a panic message and stacktrace right before the
 *  process aborts, if none have been registered beforehand.
 *
 *  Else, a default console logging hooks takes place, which for certain SDKs such as Android,
 *  yields hard-to-access crash reports.
 *
 *  Do note that this "handler" does not really "handle" anything, insofar it cannot prevent the
 *  impending doom/abort. It's really just a reporter, to say the last words of the process.
 */
void
/* fn */ dittoffi_ditto_set_panic_handler (
    dittoffi_panic_handler_t panic_handler);

/** <No documentation available> */
void
/* fn */ dittoffi_ditto_stop_sync (
    CDitto_t const * ditto);

/** <No documentation available> */
slice_boxed_uint8_t
/* fn */ dittoffi_ditto_transport_config (
    CDitto_t const * ditto);

/** \brief
 *  Internal helper function to do integration testing of panics in the SDKs.
 */
int32_t
/* fn */ dittoffi_ditto_trigger_test_panic (void);

/** \brief
 *  Internal helper function to do integration testing of panics in the SDKs.
 */
void
/* fn */ dittoffi_ditto_trigger_test_panic_in_background (void);

/** \brief
 *  Same as `ditto_make`, but properly fallible (but not yet `async`).
 */
dittoffi_result_CDitto_ptr_t
/* fn */ dittoffi_ditto_try_new_blocking (
    char const * working_dir,
    CIdentityConfig_t * identity_config,
    HistoryTracking_t history_tracking,
    char const * experimental_passphrase,
    TransportConfigMode_t transport_config_mode);

/** \brief
 *  Set the transport config, start/stop transports as needed.
 *
 *  * `ditto` - The Ditto instance.
 *  * `transport_config_cbor` - `TransportConfig` serialized as CBOR.
 *  * `should_validate` - If true, the `TransportConfig` will be validated before being set.
 *
 *  Returns error on failure to deserialize `transport_config_cbor`, or if `should_validate` is true
 *  and the `TransportConfig` fails validation.
 */
dittoffi_result_void_t
/* fn */ dittoffi_ditto_try_set_transport_config (
    CDitto_t const * ditto,
    slice_ref_uint8_t transport_config_cbor,
    bool should_validate);

/** <No documentation available> */
dittoffi_result_void_t
/* fn */ dittoffi_ditto_try_start_sync (
    CDitto_t const * ditto);

/** \brief
 *  Whether to use a helper thread for calling into the panic handler.
 *
 *  Defaults to `false` when the `js` feature is enabled (Node.js &
 *  Wasm), and `true` otherwise.
 */
void
/* fn */ dittoffi_ditto_use_helper_thread_for_panic_handler_internal (
    bool value);

/** \brief
 *  `Arc<dyn Send + Sync + Fn(A1) -> Ret>`
 */
typedef struct ArcDynFn1_void_StreamCandidate {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, StreamCandidate_t);

    /** <No documentation available> */
    void (*release)(void *);

    /** <No documentation available> */
    void (*retain)(void *);
} ArcDynFn1_void_StreamCandidate_t;

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_ConnectionResult_Layout {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, ConnectionResult_Layout_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_ConnectionResult_Layout_t;

/** <No documentation available> */
typedef struct IEndpointVTable {
    /** <No documentation available> */
    void (*release_vptr)(Erased_t *);

    /** <No documentation available> */
    Erased_t * (*retain_vptr)(Erased_t const *);

    /** \brief
     *  Binds a callback to a new topic.
     */
    BindResult_Layout_t (*bind_topic)(Erased_t const *, slice_ref_uint8_t, Reliability_t, ArcDynFn1_void_StreamCandidate_t);

    /** \brief
     *  Attempts to establish a connection, yielding a connection result once done.
     */
    ConnectionHandle_t (*connect)(Erased_t const *, void_const_ptr_2_array_t, slice_ref_uint8_t, Reliability_t, bool, BoxDynFnMut1_void_ConnectionResult_Layout_t, uint32_t, Bytes_t);

    /** \brief
     *  Returns a hash of the endpoint's type ID, allowing internal code to identify the endpoint
     *  type and downcast it if necessary.
     *
     *  There's never any point in using it outside of Ditto's codebase.
     */
    uint64_t (*type_id)(Erased_t const *);
} IEndpointVTable_t;

/** <No documentation available> */
typedef struct VirtualPtr__Erased_ptr_IEndpointVTable {
    /** <No documentation available> */
    Erased_t * ptr;

    /** <No documentation available> */
    IEndpointVTable_t vtable;
} VirtualPtr__Erased_ptr_IEndpointVTable_t;

/** \brief
 *  # Ditto Data Streams
 *  Ditto Data Streams allow you to send datagrams across a Ditto mesh.
 *
 *  This structure is the core accessor to the Ditto Data Streams, which may remind you of some TCP
 *  APIs you've seen before (except this one can work without an IP connection too!).
 *
 *  While exploring the API from [`Endpoint::bind_topic`], [`Endpoint::connect`] and the examples
 *  their docs contain is probably the easiest way to approach it, there are a few subjects that are
 *  global to the API: giving them a look could be helpful.
 *
 *  The entire API is built around the builder pattern: a rather convenient way to explore it is to
 *  simply let your code completion guide you around it.
 *
 *  ## Topics
 *  Much like TCP and UDP have ports, Ditto Data Streams have `topic`s: instead of integers, you can
 *  name your ports after anything you like!
 *
 *  The equivalent of binding a socket is to use [`Endpoint::bind_topic`], to which you'll provide a
 *  topic (or name).
 *
 *  Any attempt to [`Endpoint::connect`] to your peer will have to specify on which topic the
 *  connection should be made, the connection appearing as a new [`Stream`] for your [`Acceptor`].
 *
 *  ## [`Payload`] and [`IntoPayload`]
 *  To carry data around, the Ditto Data Streams API uses [`Payload`]s, also known as
 *  [`safer_ffi::bytes::Bytes`]: much like the wider known [`bytes::Bytes`](https://docs.rs/bytes/latest/bytes/struct.Bytes.html), it's a cheaply cloneable and sliceable chunk of contiguous memory... But it does have a few low-level tricks up its sleeve to be even more efficient.
 *
 *  And while it's easy enough to construct it from common owned slice types, [`IntoPayload`] is a
 *  very friendly option to make serialization less verbose, yet explicit and flexible.
 *
 *  ## [`IntoChannel`]: We promise, it's not as scary as it looks
 *  In this API, anytime we think you may want the choice between closures and channels to handle
 *  certain events you could subscribe to, we've used the following signature pattern:
 *  ```
 *  # mod dittolive_ditto {
 *  #   pub mod preview {
 *  #       pub use dittolive_ditto_base::*;
 *  #   }
 *  # }
 *  # use dittolive_ditto::preview::datastreams::{Channel, IntoChannel};
 *  # struct Event; struct Subscriber<T>(T);
 *  fn subscribe<OverloadId, Handler>(handler: Handler) -> Subscriber<Handler::Receiver>
 *  where
 *  Handler: IntoChannel<OverloadId, Event>,
 *  Handler::Sender: Channel<OverloadId, Event>,
 *  # {unimplemented!()}
 *  ```
 *
 *  While this looks imposing, it's actually a very magic formula: it allows you to write little to
 *  no boiler plate in 99% of cases, while giving you the flexibility to use any handler you please
 *  and allowing us to find every trick possible to minimize the overhead of calling your handler.
 *
 *  In most cases, all you need to do to use such an API is to call it with
 *  - a closure: `let handle = subscribe(|e: Event| println!("{e}"));` (you may want to keep
 *  `handle` around, as dropping it will cancel that subscription).
 *  - any channel implementation you like: `let handle = subscribe(std::sync::mpsc::channel())`
 *  (here, `handle` will deref to the receiver half of the channel, letting you call
 *  `handle.recv()` whenever you like).
 *
 *  `OverloadId` is actually a charm that tricks the compiler into letting you bypass the orphan
 *  rule<sup>[(1)](https://doc.rust-lang.org/book/ch10-02-traits.html#:~:text=orphan%20rule)[(2)](https://github.com/Ixrec/rust-orphan-rules)</sup>, and is described in more detail in [`IntoChannel`]'s documentation, which also contains an
 *  example of how to use that trick to add support for [`flume`](https://crates.io/crates/flume)'s excellent channel implementation
 *  to Ditto's Data Streams API.
 */
typedef struct Endpoint {
    /** <No documentation available> */
    VirtualPtr__Erased_ptr_IEndpointVTable_t inner;
} Endpoint_t;

/** <No documentation available> */
BindResult_Layout_t
/* fn */ dittoffi_endpoint_bind_topic (
    Endpoint_t const * endpoint,
    slice_ref_uint8_t topic,
    Reliability_t reliability,
    ArcDynFn1_void_StreamCandidate_t on_accept);

/** <No documentation available> */
ConnectionHandle_t
/* fn */ dittoffi_endpoint_connect (
    Endpoint_t const * endpoint,
    slice_ref_uint8_t to,
    slice_ref_uint8_t topic,
    Reliability_t reliability,
    bool request_compression,
    uint32_t timeout_ms,
    Bytes_t arguments,
    BoxDynFnMut1_void_ConnectionResult_Layout_t then);

/** <No documentation available> */
void
/* fn */ dittoffi_endpoint_release (
    Endpoint_t * endpoint);

/** <No documentation available> */
Endpoint_t
/* fn */ dittoffi_endpoint_retain (
    Endpoint_t const * endpoint);

/** \brief
 *  The error codes for `ditto_error_t`
 */
typedef enum dittoffi_error_code {
    /** \brief
     *  The license is valid but expired.
     */
    DITTOFFI_ERROR_CODE_ACTIVATION_LICENSE_TOKEN_EXPIRED,
    /** \brief
     *  The license signature failed verification. This could be due to incorrectly
     *  encoded/truncated data or could indicate tampering.
     */
    DITTOFFI_ERROR_CODE_ACTIVATION_LICENSE_TOKEN_INVALID,
    /** \brief
     *  The provided license data was from a future version of Ditto and is incompatible with this
     *  version.
     */
    DITTOFFI_ERROR_CODE_ACTIVATION_LICENSE_UNSUPPORTED_FUTURE_VERSION,
    /** \brief
     *  The operation failed because the Ditto instance is not yet activated, which is achieved by
     *  setting a valid license token.
     */
    DITTOFFI_ERROR_CODE_ACTIVATION_NOT_ACTIVATED,
    /** \brief
     *  Activation (via setting a valid license token) is unnecessary for the active identity type.
     */
    DITTOFFI_ERROR_CODE_ACTIVATION_UNNECESSARY,
    /** \brief
     *  The operation failed because an authentication expiration handler has not yet been set.
     */
    DITTOFFI_ERROR_CODE_AUTHENTICATION_EXPIRATION_HANDLER_MISSING,
    /** \brief
     *  Invalid input provided for base64 decoding.
     */
    DITTOFFI_ERROR_CODE_BASE64_INVALID,
    /** \brief
     *  Invalid CBOR-encoded input.
     */
    DITTOFFI_ERROR_CODE_CBOR_INVALID,
    /** \brief
     *  Unsupported CBOR type.
     */
    DITTOFFI_ERROR_CODE_CBOR_UNSUPPORTED,
    /** <No documentation available> */
    DITTOFFI_ERROR_CODE_CRDT,
    /** <No documentation available> */
    DITTOFFI_ERROR_CODE_DIFFER_IDENTITY_KEY_PATH_INVALID,
    /** \brief
     *  Dql query execution failed in flight.
     */
    DITTOFFI_ERROR_CODE_DQL_EVALUATION_ERROR,
    /** \brief
     *  Invalid CBOR-encoded query arguments.
     */
    DITTOFFI_ERROR_CODE_DQL_INVALID_QUERY_ARGS,
    /** \brief
     *  Failed to compile the given query.
     *
     *  For more information on Ditto's query language see:
     *  <https://ditto.com/link/dql-guide>
     */
    DITTOFFI_ERROR_CODE_DQL_QUERY_COMPILATION,
    /** \brief
     *  Unsupported features were used in a DQL statement or query.
     */
    DITTOFFI_ERROR_CODE_DQL_UNSUPPORTED,
    /** \brief
     *  Unexpected passphrase provided for the currently unencrypted store.
     */
    DITTOFFI_ERROR_CODE_ENCRYPTION_EXTRANEOUS_PASSPHRASE_GIVEN,
    /** \brief
     *  Incorrect passphrase provided for the currently encrypted store.
     */
    DITTOFFI_ERROR_CODE_ENCRYPTION_PASSPHRASE_INVALID,
    /** \brief
     *  Missing passphrase for the currently encrypted store.
     */
    DITTOFFI_ERROR_CODE_ENCRYPTION_PASSPHRASE_NOT_GIVEN,
    /** \brief
     *  Javascript only. Missing `await` on outstanding store operation.
     */
    DITTOFFI_ERROR_CODE_JS_FLOATING_STORE_OPERATION,
    /** \brief
     *  An I/O operation failed because the specified entity (such as a file) already exists.
     */
    DITTOFFI_ERROR_CODE_IO_ALREADY_EXISTS,
    /** \brief
     *  An I/O operation failed because the specified entity (such as a file) was not found.
     */
    DITTOFFI_ERROR_CODE_IO_NOT_FOUND,
    /** \brief
     *  An I/O operation failed.
     */
    DITTOFFI_ERROR_CODE_IO_OPERATION_FAILED,
    /** \brief
     *  An I/O operation failed because the necessary privileges to complete it were not present.
     */
    DITTOFFI_ERROR_CODE_IO_PERMISSION_DENIED,
    /** \brief
     *  Outstanding usage of ditto's working directory detected when trying to instantiate a new
     *  `Ditto`, which would have led to concurrent usage of the backing database files.
     */
    DITTOFFI_ERROR_CODE_LOCKED_DITTO_WORKING_DIRECTORY,
    /** \brief
     *  A query to alter or retrieve a system parameter (ALTER SYSTEM or SHOW) failed.
     */
    DITTOFFI_ERROR_CODE_PARAMETER_QUERY,
    /** <No documentation available> */
    DITTOFFI_ERROR_CODE_STORE_DATABASE,
    /** \brief
     *  Found an invalid document id.
     */
    DITTOFFI_ERROR_CODE_STORE_DOCUMENT_ID,
    /** \brief
     *  The requested document could not be found.
     */
    DITTOFFI_ERROR_CODE_STORE_DOCUMENT_NOT_FOUND,
    /** <No documentation available> */
    DITTOFFI_ERROR_CODE_STORE_QUERY,
    /** \brief
     *  A mutating DQL query was attempted using a read-only transaction.
     */
    DITTOFFI_ERROR_CODE_STORE_TRANSACTION_READ_ONLY,
    /** \brief
     *  Error from the transport layer.
     */
    DITTOFFI_ERROR_CODE_TRANSPORT,
    /** \brief
     *  Feature is not (yet?) supported (on this platform?).
     *
     *  See the documentation of the feature for more info.
     */
    DITTOFFI_ERROR_CODE_UNSUPPORTED,
    /** \brief
     *  Exceeded a depth limit.
     */
    DITTOFFI_ERROR_CODE_VALIDATION_DEPTH_LIMIT_EXCEEDED,
    /** \brief
     *  Invalid CBOR provided.
     */
    DITTOFFI_ERROR_CODE_VALIDATION_INVALID_CBOR,
    /** \brief
     *  Invalid JSON provided.
     */
    DITTOFFI_ERROR_CODE_VALIDATION_INVALID_JSON,
    /** \brief
     *  Invalid TransportConfig.
     */
    DITTOFFI_ERROR_CODE_VALIDATION_INVALID_TRANSPORT_CONFIG,
    /** \brief
     *  Invalid DittoConfig.
     */
    DITTOFFI_ERROR_CODE_VALIDATION_INVALID_DITTO_CONFIG,
    /** \brief
     *  The value was not a map.
     */
    DITTOFFI_ERROR_CODE_VALIDATION_NOT_A_MAP,
    /** \brief
     *  Exceeded the size limit.
     */
    DITTOFFI_ERROR_CODE_VALIDATION_SIZE_LIMIT_EXCEEDED,
    /** \brief
     *  An unknown error occurred.
     */
    DITTOFFI_ERROR_CODE_UNKNOWN,
    /** \brief
     *  Some not-yet-categorized error occurred.
     */
    DITTOFFI_ERROR_CODE_INTERNAL,
} dittoffi_error_code_t;

/** <No documentation available> */
dittoffi_error_code_t
/* fn */ dittoffi_error_code (
    dittoffi_error_t const * error);

/** <No documentation available> */
char *
/* fn */ dittoffi_error_description (
    dittoffi_error_t const * error);

/** <No documentation available> */
void
/* fn */ dittoffi_error_free (
    dittoffi_error_t * error);

/** \brief
 *  Internal helper function to extract the inner error code from `Internal` errors.
 *
 *  Must only be called after having checked that the `dittoffi_error_code()` does yield
 *  `FfiErrorCode::Internal`, lest it panic.
 */
DittoErrorCode_t
/* fn */ dittoffi_error_internal_get_legacy_error_code (
    dittoffi_error_t const * error);

/** \brief
 *  Returns a handle to the experimental endpoint, initializing it if necessary.
 *
 *  Note that as of writing of this doc, RUSTFLAGS must also contain `--cfg tokio_unstable` for
 *  ditto to compile successfully.
 */
Endpoint_t
/* fn */ dittoffi_get_preview_datastreams (
    CDitto_t const * ditto);

/** \brief
 *  Returns a human-readable SDK version string, restricted to the SemVer
 *  "number" (including the pre-release specifier, if any).
 *
 *  The returned string must be freed.
 */
char *
/* fn */ dittoffi_get_sdk_semver (void);

/** <No documentation available> */
Bytes_t
/* fn */ dittoffi_inbound_payload (
    Inbound_t const * inbound);

/** <No documentation available> */
void
/* fn */ dittoffi_inbound_release (
    Inbound_t * inbound);

/** <No documentation available> */
Inbound_t
/* fn */ dittoffi_inbound_retain (
    Inbound_t const * inbound);

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_dittoffi_result_uint64 {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, dittoffi_result_uint64_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_dittoffi_result_uint64_t;

/** \brief
 *  Continuation (`repr_c::Box<dyn FnMut(…)>` FFI-safe callback) to be used as
 *  the *completion handler* for conceptually-`async` APIs.
 */
typedef BoxDynFnMut1_void_dittoffi_result_uint64_t continuation_dittoffi_result_uint64_t;

/** \brief
 *  Export previously collected on-disk logs to a single file at the specified path.
 *
 *  Returns one of the following errors on failure:
 *
 *  - [`FfiError::IoNotFound`]
 *  - [`FfiError::IoPermissionDenied`]
 *  - [`FfiError::IoAlreadyExists`]
 *  - [`FfiError::IoOperationFailed`]
 *  - [`FfiError::Unsupported`]
 *  - [`FfiError::Unknown`]
 */
void
/* fn */ dittoffi_logger_try_export_to_file_async (
    char const * dest_path,
    continuation_dittoffi_result_uint64_t continuation);

/** \brief
 *  The same as `ditto_make` but it allows for an explicit value for `TransportConfigMode` to be
 *  provided.
 */
CDitto_t *
/* fn */ dittoffi_make_with_transport_config_mode (
    char const * working_dir,
    CIdentityConfig_t * identity_config,
    HistoryTracking_t history_tracking,
    TransportConfigMode_t transport_config_mode);

/** \brief
 *  Dispose of the panic handle (even if the process is about to abort anyways).
 */
void
/* fn */ dittoffi_panic_free (
    dittoffi_panic_t * __arg_0);

/** \brief
 *  Extract the panic message.
 */
char *
/* fn */ dittoffi_panic_message (
    dittoffi_panic_t const * panic);

/** \brief
 *  Extract the stacktrace whence the panic occurred, currently as a C string with newlines in it.
 */
char *
/* fn */ dittoffi_panic_stack_trace_string (
    dittoffi_panic_t const * panic);

/** \brief
 *  Clones a `PeerPubkey`.
 */
void_const_ptr_2_array_t
/* fn */ dittoffi_peer_pubkey_clone (
    void_const_ptr_2_array_t const * peer_pubkey);

/** <No documentation available> */
void
/* fn */ dittoffi_peer_pubkey_delete (
    void_const_ptr_2_array_t key);

/** \brief
 *  Simplified for lighter documentation, but the actual impls
 *  range from `Tuple1` up to `Tuple6`.
 */
typedef struct Tuple2_bool_void_const_ptr_2_array {
    /** <No documentation available> */
    bool _0;

    /** <No documentation available> */
    void_const_ptr_2_array_t _1;
} Tuple2_bool_void_const_ptr_2_array_t;

/** \brief
 *  Parses a `PeerPubkey` from a PeerPubkeyStr, returning `TaggedOption::None` in case of
 *  failure.
 */
Tuple2_bool_void_const_ptr_2_array_t
/* fn */ dittoffi_peer_pubkey_from_str (
    slice_ref_uint8_t s);

/** \brief
 *  Converts a `PeerPubkey` into a string through its `Display` implementation.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_peer_pubkey_to_cstr (
    void_const_ptr_2_array_t const * peer_pubkey);

/** \brief
 *  Returns the current presence graph as a JSON string in a UTF-8 encoded byte array.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_presence_graph (
    CDitto_t const * ditto);

/** \brief
 *  An opaque handle to a presence observer.
 *
 *  - Use [`dittoffi_presence_register_observer_throws`] to create a new observer.
 *  - Use [`dittoffi_presence_observer_cancel`] to cancel an observer.
 */
typedef struct dittoffi_presence_observer dittoffi_presence_observer_t;

/** \brief
 *  Cancels the presence observer.
 */
void
/* fn */ dittoffi_presence_observer_cancel (
    dittoffi_presence_observer_t const * observer);

/** \brief
 *  Free a boxed `FfiPresenceObserver`.
 */
void
/* fn */ dittoffi_presence_observer_free (
    dittoffi_presence_observer_t * observer);

/** \brief
 *  Returns the ID of the presence observer.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_presence_observer_id (
    dittoffi_presence_observer_t const * observer);

/** \brief
 *  Checks whether the presence observer is cancelled.
 */
bool
/* fn */ dittoffi_presence_observer_is_cancelled (
    dittoffi_presence_observer_t const * observer);

/** \brief
 *  Getter for the `peer_metadata` as a JSON (string / UTF-8 data).
 */
slice_boxed_uint8_t
/* fn */ dittoffi_presence_peer_metadata_json (
    CDitto_t const * ditto);

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_slice_boxed_uint8 {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, slice_boxed_uint8_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_slice_boxed_uint8_t;

/** <No documentation available> */
typedef struct dittoffi_result_dittoffi_presence_observer_ptr {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    dittoffi_presence_observer_t * success;
} dittoffi_result_dittoffi_presence_observer_ptr_t;

/** \brief
 *  Registers a new [`FfiPresenceObserver`].
 *
 *  This will call the provided callback whenever the presence graph changes.
 *
 *  To cancel the observer, use [`dittoffi_presence_observer_cancel`].
 */
dittoffi_result_dittoffi_presence_observer_ptr_t
/* fn */ dittoffi_presence_register_observer_throws (
    CDitto_t const * ditto,
    BoxDynFnMut1_void_slice_boxed_uint8_t callback);

/** <No documentation available> */
typedef struct FfiConnectionRequestHandlerVTable {
    /** <No documentation available> */
    void (*release_vptr)(Erased_t *);

    /** <No documentation available> */
    Erased_t * (*retain_vptr)(Erased_t const *);

    /** <No documentation available> */
    void (*on_connecting)(Erased_t const *, dittoffi_connection_request_t *);
} FfiConnectionRequestHandlerVTable_t;

/** <No documentation available> */
typedef struct VirtualPtr__Erased_ptr_FfiConnectionRequestHandlerVTable {
    /** <No documentation available> */
    Erased_t * ptr;

    /** <No documentation available> */
    FfiConnectionRequestHandlerVTable_t vtable;
} VirtualPtr__Erased_ptr_FfiConnectionRequestHandlerVTable_t;

/** \brief
 *  Register a function that will be called every time a peer connection attempt is made.
 *  The function can return true to continue connecting, and false to reject the connection,
 *  based on the supplied metadata about the peer.
 */
void
/* fn */ dittoffi_presence_set_connection_request_handler (
    CDitto_t const * ditto,
    VirtualPtr__Erased_ptr_FfiConnectionRequestHandlerVTable_t ffi_handler);

/** \brief
 *  Sets the signed peer info / peer metadata to which the `on_connecting` /
 *  `connectionRequestHandler` callback shall have access.
 *
 *  The `peer_info` is expected to represent the UTF-8 bytes of a serialized JSON instead of CBOR.
 */
dittoffi_result_void_t
/* fn */ dittoffi_presence_set_peer_metadata_json_throws (
    CDitto_t const * ditto,
    slice_ref_uint8_t peer_info);

/** <No documentation available> */
dittoffi_result_void_t
/* fn */ dittoffi_presence_try_set_peer_metadata_json (
    CDitto_t const * ditto,
    slice_ref_uint8_t peer_info);

/** <No documentation available> */
typedef struct dittoffi_query_result dittoffi_query_result_t;

/** \brief
 *  Returns the commit ID for this query result, or zero if there is none.
 *
 *  SDK implementations should generally call [`dittoffi_query_result_has_commit_id()`] first, and
 *  return the appropriate language specific "no value" value if that function returns false.
 */
uint64_t
/* fn */ dittoffi_query_result_commit_id (
    dittoffi_query_result_t const * result);

/** <No documentation available> */
void
/* fn */ dittoffi_query_result_free (
    dittoffi_query_result_t * result);

/** \brief
 *  Indicates whether this query result has a commit ID.
 *
 *  SDK implementations should generally call this function before calling
 *  [`dittoffi_query_result_commit_id()`], and return the appropriate language specific
 *  "no value" value if this function returns false.
 */
bool
/* fn */ dittoffi_query_result_has_commit_id (
    dittoffi_query_result_t const * result);

/** <No documentation available> */
dittoffi_query_result_item_t *
/* fn */ dittoffi_query_result_item_at (
    dittoffi_query_result_t const * result,
    size_t idx);

/** <No documentation available> */
slice_boxed_uint8_t
/* fn */ dittoffi_query_result_item_cbor (
    dittoffi_query_result_item_t const * item);

/** <No documentation available> */
size_t
/* fn */ dittoffi_query_result_item_count (
    dittoffi_query_result_t const * result);

/** <No documentation available> */
void
/* fn */ dittoffi_query_result_item_free (
    dittoffi_query_result_item_t * item);

/** <No documentation available> */
char *
/* fn */ dittoffi_query_result_item_json (
    dittoffi_query_result_item_t const * item);

/** <No documentation available> */
typedef struct dittoffi_result_dittoffi_query_result_item_ptr {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    dittoffi_query_result_item_t * success;
} dittoffi_result_dittoffi_query_result_item_ptr_t;

/** \brief
 *  Create a query result item from JSON data.
 *
 *  `query_result_item` is expected to represent the UTF-8 bytes of a serialized JSON instead of
 *  CBOR.
 *
 *  Note that this is only expected to be called by SDKs as part of generating test data, e.g. for
 *  testing behaviour of the differ.
 */
dittoffi_result_dittoffi_query_result_item_ptr_t
/* fn */ dittoffi_query_result_item_new (
    slice_ref_uint8_t query_result_item);

/** <No documentation available> */
slice_boxed_uint8_t
/* fn */ dittoffi_query_result_mutated_document_id_at (
    dittoffi_query_result_t const * result,
    size_t idx);

/** <No documentation available> */
size_t
/* fn */ dittoffi_query_result_mutated_document_id_count (
    dittoffi_query_result_t const * result);

/** <No documentation available> */
CancellationResult_Layout_t
/* fn */ dittoffi_send_handle_cancel (
    VirtualPtr__Erased_ptr_ISendHandleVTable_t const * handle);

/** <No documentation available> */
SendStatus_t
/* fn */ dittoffi_send_handle_poll (
    VirtualPtr__Erased_ptr_ISendHandleVTable_t const * handle);

/** <No documentation available> */
void
/* fn */ dittoffi_send_handle_release (
    VirtualPtr__Erased_ptr_ISendHandleVTable_t * handle);

/** <No documentation available> */
VirtualPtr__Erased_ptr_ISendHandleVTable_t
/* fn */ dittoffi_send_handle_retain (
    VirtualPtr__Erased_ptr_ISendHandleVTable_t const * handle);

/** <No documentation available> */
void
/* fn */ dittoffi_send_handle_set_on_change (
    VirtualPtr__Erased_ptr_ISendHandleVTable_t const * handle,
    BoxDynFnMut1_void_SendStatus_t callback,
    bool keep_previous);

/** \brief
 *  Alias for `Ditto`, to better convey the notion of a store handle for store APIs,
 *  TownHouse™-style.
 *
 *  SDK code casts references to `Ditto`s into references to `FfiStore`s, so it's important for
 *  safety that FfiStore doesn't add future invariants without checking `Transaction::store_ptr`
 *  (and potentially other places too) to make sure those invariants are upheld.
 */
typedef CDitto_t dittoffi_store_t;

/** \brief
 *  FFI appropriate representation of the options available when beginning a transaction.
 */
typedef struct dittoffi_store_begin_transaction_options {
    /** \brief
     *  Whether the transaction is read-only. Defaults to `false`.
     */
    bool is_read_only;

    /** \brief
     *  An optional hint for the transaction. This is often useful for identifying a transaction in
     *  logs.
     */
    char const * hint;
} dittoffi_store_begin_transaction_options_t;

/** <No documentation available> */
typedef struct dittoffi_transaction dittoffi_transaction_t;

/** <No documentation available> */
typedef struct dittoffi_result_dittoffi_transaction_ptr {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    dittoffi_transaction_t * success;
} dittoffi_result_dittoffi_transaction_ptr_t;

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_dittoffi_result_dittoffi_transaction_ptr {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, dittoffi_result_dittoffi_transaction_ptr_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_dittoffi_result_dittoffi_transaction_ptr_t;

/** \brief
 *  Continuation (`repr_c::Box<dyn FnMut(…)>` FFI-safe callback) to be used as
 *  the *completion handler* for conceptually-`async` APIs.
 */
typedef BoxDynFnMut1_void_dittoffi_result_dittoffi_transaction_ptr_t continuation_dittoffi_result_dittoffi_transaction_ptr_t;

/** \brief
 *  Creates a new transaction.
 */
void
/* fn */ dittoffi_store_begin_transaction_async_throws (
    dittoffi_store_t const * store,
    dittoffi_store_begin_transaction_options_t options,
    continuation_dittoffi_result_dittoffi_transaction_ptr_t continuation);

/** <No documentation available> */
dittoffi_store_begin_transaction_options_t
/* fn */ dittoffi_store_begin_transaction_options_make (void);

/** \brief
 *  An opaque, unique handle for a `StoreObserver`.
 *
 *  This handle will be held by SDK callers above the FFI boundary. It is a required input to most
 *  of the other FFI store observer functions.
 */
typedef struct dittoffi_store_observer dittoffi_store_observer_t;

/** \brief
 *  Cancels the observer and removes it from the list of registered observers.
 */
void
/* fn */ dittoffi_store_observer_cancel (
    dittoffi_store_observer_t const * observer);

/** \brief
 *  Free an [`FfiStoreObserver`].
 */
void
/* fn */ dittoffi_store_observer_free (
    dittoffi_store_observer_t * _observer);

/** \brief
 *  Returns the inner ID of the given observer.
 *
 *  This is an implementation detail and should not be relied upon by third parties.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_store_observer_id (
    dittoffi_store_observer_t const * observer);

/** \brief
 *  Returns true if the given observer is cancelled.
 */
bool
/* fn */ dittoffi_store_observer_is_cancelled (
    dittoffi_store_observer_t const * observer);

/** \brief
 *  Returns the CBOR-serialized DQL query arguments of the given observer, if any were given.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_store_observer_query_arguments (
    dittoffi_store_observer_t const * observer);

/** \brief
 *  Returns the CBOR-serialized DQL query arguments of the given observer, if any were given.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_store_observer_query_arguments_cbor (
    dittoffi_store_observer_t const * observer);

/** \brief
 *  Returns the JSON-serialized DQL query arguments of the given observer, if any were given.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_store_observer_query_arguments_json (
    dittoffi_store_observer_t const * observer);

/** \brief
 *  Returns the DQL query string of the given observer.
 */
char *
/* fn */ dittoffi_store_observer_query_string (
    dittoffi_store_observer_t const * observer);

/** \brief
 *  Same as [`Vec<T>`][`rust::Vec`], but with guaranteed `#[repr(C)]` layout
 */
typedef struct Vec_dittoffi_store_observer_ptr {
    /** <No documentation available> */
    dittoffi_store_observer_t * * ptr;

    /** <No documentation available> */
    size_t len;

    /** <No documentation available> */
    size_t cap;
} Vec_dittoffi_store_observer_ptr_t;

/** \brief
 *  Returns a list of all registered observers.
 */
Vec_dittoffi_store_observer_ptr_t
/* fn */ dittoffi_store_observers (
    CDitto_t const * ditto);

/** \brief
 *  Free a Vec of [`FfiStoreObserver`]s.
 *
 *  # IMPORTANT
 *
 *  This freeing function ignores the given `.len` and treats it as if `.len = 0` (to avoid
 *  double-freeing).
 *
 *  SDK callers should have taken ownership of each individual `FfiStoreObserver` (either by having
 *  freed each, or by having wrapped them in some SDK class that eventually will), in order to avoid
 *  memory leaks.
 */
void
/* fn */ dittoffi_store_observers_free_sparse (
    Vec_dittoffi_store_observer_ptr_t vec);

/** \brief
 *  `Arc<dyn Send + Sync + Fn() -> Ret>`
 */
typedef struct ArcDynFn0_void {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *);

    /** <No documentation available> */
    void (*release)(void *);

    /** <No documentation available> */
    void (*retain)(void *);
} ArcDynFn0_void_t;

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A2, A1) -> Ret>`
 */
typedef struct BoxDynFnMut2_void_dittoffi_query_result_ptr_ArcDynFn0_void {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, dittoffi_query_result_t *, ArcDynFn0_void_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut2_void_dittoffi_query_result_ptr_ArcDynFn0_void_t;

/** \brief
 *  Ffi-compatible callback wrapper for store observers.
 *
 *  # Notes
 *
 *  - SDK clients construct this callback and we call it sequentially (non-overlapping), hence
 *  `FnMut`.
 */
typedef BoxDynFnMut2_void_dittoffi_query_result_ptr_ArcDynFn0_void_t dittoffi_store_observation_handler_with_signal_next_t;

/** <No documentation available> */
typedef struct dittoffi_result_dittoffi_store_observer_ptr {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    dittoffi_store_observer_t * success;
} dittoffi_result_dittoffi_store_observer_ptr_t;

/** \brief
 *  Registers a new `StoreObserver` for the given DQL query and arguments.
 *
 *  The observer will be notified of changes to the query results.
 */
dittoffi_result_dittoffi_store_observer_ptr_t
/* fn */ dittoffi_store_register_observer_throws (
    CDitto_t const * ditto,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    dittoffi_store_observation_handler_with_signal_next_t handler);

/** \brief
 *  Returns all transactions currently in flight.
 */
dittoffi_cbor_data_t
/* fn */ dittoffi_store_transactions (
    dittoffi_store_t const * ffi_store);

/** <No documentation available> */
void
/* fn */ dittoffi_stream_add_on_close (
    Stream_t const * stream,
    BoxDynFnMut1_void_StreamStatus_t continuation);

/** <No documentation available> */
Bytes_t
/* fn */ dittoffi_stream_candidate_arguments (
    StreamCandidate_t const * candidate);

/** <No documentation available> */
Tuple2_bool_Stream_t
/* fn */ dittoffi_stream_candidate_open (
    StreamCandidate_t const * candidate,
    BoxDynFnMut1_void_Inbound_t on_recv,
    Bytes_t arguments);

/** <No documentation available> */
Tuple2_bool_Stream_t
/* fn */ dittoffi_stream_candidate_open_write_only (
    StreamCandidate_t const * candidate,
    Bytes_t arguments);

/** <No documentation available> */
void_const_ptr_2_array_t
/* fn */ dittoffi_stream_candidate_peer_pubkey (
    StreamCandidate_t const * candidate);

/** <No documentation available> */
void
/* fn */ dittoffi_stream_candidate_release (
    StreamCandidate_t * candidate);

/** <No documentation available> */
StreamCandidate_t
/* fn */ dittoffi_stream_candidate_retain (
    StreamCandidate_t const * candidate);

/** <No documentation available> */
Topic_t
/* fn */ dittoffi_stream_candidate_topic (
    StreamCandidate_t const * candidate);

/** <No documentation available> */
StreamStatus_t
/* fn */ dittoffi_stream_current_status (
    Stream_t const * stream);

/** <No documentation available> */
size_t
/* fn */ dittoffi_stream_max_send_size (
    Stream_t const * stream);

/** <No documentation available> */
void_const_ptr_2_array_t
/* fn */ dittoffi_stream_peer_pubkey (
    Stream_t const * stream);

/** <No documentation available> */
void
/* fn */ dittoffi_stream_release (
    Stream_t * stream);

/** <No documentation available> */
Stream_t
/* fn */ dittoffi_stream_retain (
    Stream_t const * stream);

/** <No documentation available> */
VirtualPtr__Erased_ptr_ISendHandleVTable_t
/* fn */ dittoffi_stream_send (
    Stream_t const * stream,
    Bytes_t const * payload);

/** <No documentation available> */
VirtualPtr__Erased_ptr_ISendHandleVTable_t
/* fn */ dittoffi_stream_send_slice (
    Stream_t const * stream,
    slice_ref_uint8_t slice);

/** <No documentation available> */
Topic_t
/* fn */ dittoffi_stream_topic (
    Stream_t const * stream);

/** \brief
 *  An object that causes Ditto to continuously sync documents that match a query from other peers.
 */
typedef struct dittoffi_sync_subscription dittoffi_sync_subscription_t;

/** <No documentation available> */
typedef struct dittoffi_result_dittoffi_sync_subscription_ptr {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    dittoffi_sync_subscription_t * success;
} dittoffi_result_dittoffi_sync_subscription_ptr_t;

/** \brief
 *  Create a new [`FfiSyncSubscription`] from a DQL query and arguments.
 *
 *  Until the subscription is cancelled, Ditto will continue to sync data matching the
 *  subscription's query from other peers.
 */
dittoffi_result_dittoffi_sync_subscription_ptr_t
/* fn */ dittoffi_sync_register_subscription_throws (
    CDitto_t const * ditto,
    char const * query,
    slice_ref_uint8_t query_args_cbor);

/** \brief
 *  Cancels the given sync subscription, after which Ditto will no longer sync the data matching
 *  the subscription's query.
 */
void
/* fn */ dittoffi_sync_subscription_cancel (
    dittoffi_sync_subscription_t const * sync_subscription);

/** \brief
 *  Free a singular boxed [`FfiSyncSubscription`].
 */
void
/* fn */ dittoffi_sync_subscription_free (
    dittoffi_sync_subscription_t * __arg_0);

/** \brief
 *  Implementation detail needed for implementing Eq+Ord+Hash on `SyncSubscription`.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_sync_subscription_id (
    dittoffi_sync_subscription_t const * sync_subscription);

/** \brief
 *  Returns true if the given sync subscription has been cancelled.
 */
bool
/* fn */ dittoffi_sync_subscription_is_cancelled (
    dittoffi_sync_subscription_t const * sync_subscription);

/** \brief
 *  Returns the CBOR-serialized DQL arguments object associated with the given sync subscription, if
 *  one exists.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_sync_subscription_query_arguments_cbor (
    dittoffi_sync_subscription_t const * sync_subscription);

/** \brief
 *  Returns the JSON-serialized DQL arguments object associated with the given sync subscription, if
 *  one exists.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_sync_subscription_query_arguments_json (
    dittoffi_sync_subscription_t const * sync_subscription);

/** \brief
 *  Returns the DQL query string associated with the given sync subscription.
 */
char *
/* fn */ dittoffi_sync_subscription_query_string (
    dittoffi_sync_subscription_t const * sync_subscription);

/** \brief
 *  Same as [`Vec<T>`][`rust::Vec`], but with guaranteed `#[repr(C)]` layout
 */
typedef struct Vec_dittoffi_sync_subscription_ptr {
    /** <No documentation available> */
    dittoffi_sync_subscription_t * * ptr;

    /** <No documentation available> */
    size_t len;

    /** <No documentation available> */
    size_t cap;
} Vec_dittoffi_sync_subscription_ptr_t;

/** \brief
 *  Returns a list of all active sync subscriptions.
 */
Vec_dittoffi_sync_subscription_ptr_t
/* fn */ dittoffi_sync_subscriptions (
    CDitto_t const * ditto);

/** \brief
 *  Free a vector of boxed [`FfiSyncSubscription`]s.
 *
 *  # IMPORTANT
 *
 *  This freeing function ignores the given `.len` and treats it as if `.len = 0`
 *  (to avoid double-freeing).
 *
 *  SDK callers should have taken ownership of each individual `FfiSyncSubscription`
 *  (either by having freed each, or by having wrapped them in some SDK class that
 *  eventually will), in order to avoid memory leaks.
 */
void
/* fn */ dittoffi_sync_subscriptions_free_sparse (
    Vec_dittoffi_sync_subscription_ptr_t vec);

/** <No documentation available> */
slice_ref_uint8_t
/* fn */ dittoffi_topic_as_str (
    Topic_t const * topic);

/** \brief
 *  The action to take when completing a transaction.
 */
typedef enum dittoffi_transaction_completion_action {
    /** <No documentation available> */
    DITTOFFI_TRANSACTION_COMPLETION_ACTION_COMMIT,
    /** <No documentation available> */
    DITTOFFI_TRANSACTION_COMPLETION_ACTION_ROLLBACK,
} dittoffi_transaction_completion_action_t;

/** <No documentation available> */
typedef struct dittoffi_result_dittoffi_transaction_completion_action {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    dittoffi_transaction_completion_action_t success;
} dittoffi_result_dittoffi_transaction_completion_action_t;

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_dittoffi_result_dittoffi_transaction_completion_action {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, dittoffi_result_dittoffi_transaction_completion_action_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_dittoffi_result_dittoffi_transaction_completion_action_t;

/** \brief
 *  Continuation (`repr_c::Box<dyn FnMut(…)>` FFI-safe callback) to be used as
 *  the *completion handler* for conceptually-`async` APIs.
 */
typedef BoxDynFnMut1_void_dittoffi_result_dittoffi_transaction_completion_action_t continuation_dittoffi_result_dittoffi_transaction_completion_action_t;

/** \brief
 *  Complete a transaction asynchronously.
 *
 *  In practice this means either committing or rolling back the transaction.
 */
void
/* fn */ dittoffi_transaction_complete_async_throws (
    dittoffi_transaction_t const * transaction,
    dittoffi_transaction_completion_action_t action,
    continuation_dittoffi_result_dittoffi_transaction_completion_action_t continuation);

/** <No documentation available> */
typedef struct dittoffi_result_dittoffi_query_result_ptr {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    dittoffi_query_result_t * success;
} dittoffi_result_dittoffi_query_result_ptr_t;

/** \brief
 *  `Box<dyn 'static + Send + FnMut(A1) -> Ret>`
 */
typedef struct BoxDynFnMut1_void_dittoffi_result_dittoffi_query_result_ptr {
    /** <No documentation available> */
    void * env_ptr;

    /** <No documentation available> */
    void (*call)(void *, dittoffi_result_dittoffi_query_result_ptr_t);

    /** <No documentation available> */
    void (*free)(void *);
} BoxDynFnMut1_void_dittoffi_result_dittoffi_query_result_ptr_t;

/** \brief
 *  Continuation (`repr_c::Box<dyn FnMut(…)>` FFI-safe callback) to be used as
 *  the *completion handler* for conceptually-`async` APIs.
 */
typedef BoxDynFnMut1_void_dittoffi_result_dittoffi_query_result_ptr_t continuation_dittoffi_result_dittoffi_query_result_ptr_t;

/** \brief
 *  Execute a query using the passed in transaction.
 */
void
/* fn */ dittoffi_transaction_execute_async_throws (
    dittoffi_transaction_t const * transaction,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    continuation_dittoffi_result_dittoffi_query_result_ptr_t continuation);

/** \brief
 *  Free the passed in transaction.
 */
void
/* fn */ dittoffi_transaction_free (
    dittoffi_transaction_t * _transaction);

/** \brief
 *  Get info about a given transaction.
 */
dittoffi_cbor_data_t
/* fn */ dittoffi_transaction_info (
    dittoffi_transaction_t const * transaction);

/** \brief
 *  Returns the CBOR representation of a default [`TransportConfig`] object.
 *
 *  The intended purpose of this API is for SDKs to test their default construction logic, as well
 *  as deserialization logic.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_transport_config_new (void);

/** <No documentation available> */
void
/* fn */ dittoffi_transports_refresh_permissions (
    CDitto_t const * ditto);

/** <No documentation available> */
void
/* fn */ dittoffi_transports_update_app_in_foreground (
    CDitto_t const * ditto,
    bool in_foreground);

/** <No documentation available> */
dittoffi_result_void_t
/* fn */ dittoffi_try_add_subscription (
    CDitto_t const * ditto,
    char const * collection,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_by,
    int32_t limit,
    uint32_t offset);

/** \brief
 *  Adds a DQL sync subscription.
 *
 *  Only `SELECT` statements are supported here.
 *
 *  Returns no meaningful value but for the resulting potential `.error`.
 */
dittoffi_result_void_t
/* fn */ dittoffi_try_add_sync_subscription (
    CDitto_t const * ditto,
    char const * query,
    slice_ref_uint8_t query_args_cbor);

/** \brief
 *  Decodes a URL-safe base64-encoded string. The caller can specify whether or not they want to
 *  allow padded input. By default, both padded and unpadded input is accepted.
 *
 *  In the success case, the returned bytes need to be freed by the caller using
 *  `ditto_c_bytes_free`.
 *
 *  Throws `FfiError::Base64Invalid` if:
 *  - the input string is not a valid base64-encoded string, or
 *  - the desired padding mode is specified as `Unpadded` and the input string is padded.
 */
dittoffi_result_slice_boxed_uint8_t
/* fn */ dittoffi_try_base64_decode (
    char const * str,
    Base64PaddingMode_t padding_mode);

/** <No documentation available> */
dittoffi_result_void_t
/* fn */ dittoffi_try_collection (
    CDitto_t const * ditto,
    char const * name);

/** <No documentation available> */
dittoffi_result_bool_t
/* fn */ dittoffi_try_collection_evict (
    CDitto_t const * ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    slice_ref_uint8_t id);

/** <No documentation available> */
typedef struct dittoffi_result_Vec_slice_boxed_uint8 {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    Vec_slice_boxed_uint8_t success;
} dittoffi_result_Vec_slice_boxed_uint8_t;

/** <No documentation available> */
dittoffi_result_Vec_slice_boxed_uint8_t
/* fn */ dittoffi_try_collection_evict_by_ids (
    CDitto_t const * ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    slice_ref_slice_boxed_uint8_t ids);

/** <No documentation available> */
dittoffi_result_Vec_slice_boxed_uint8_t
/* fn */ dittoffi_try_collection_evict_query_str (
    CDitto_t const * ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_by_params,
    int32_t limit,
    uint32_t offset);

/** <No documentation available> */
typedef struct docs_and_ids {
    /** <No documentation available> */
    Vec_CDocument_ptr_t documents;

    /** <No documentation available> */
    Vec_slice_boxed_uint8_t ids;
} docs_and_ids_t;

/** <No documentation available> */
typedef struct dittoffi_result_docs_and_ids {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    docs_and_ids_t success;
} dittoffi_result_docs_and_ids_t;

/** <No documentation available> */
dittoffi_result_docs_and_ids_t
/* fn */ dittoffi_try_collection_find_by_ids (
    CDitto_t const * ditto,
    char const * coll_name,
    slice_ref_slice_boxed_uint8_t ids,
    CReadTransaction_t * transaction);

/** <No documentation available> */
typedef struct dittoffi_result_CDocument_ptr {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    CDocument_t * success;
} dittoffi_result_CDocument_ptr_t;

/** \brief
 *  [js only] Returns `-1` in case of outstanding non-`awaited` transaction operation.
 */
dittoffi_result_CDocument_ptr_t
/* fn */ dittoffi_try_collection_get (
    CDitto_t const * _ditto,
    char const * coll_name,
    slice_ref_uint8_t id,
    CReadTransaction_t * transaction);

/** <No documentation available> */
dittoffi_result_slice_boxed_uint8_t
/* fn */ dittoffi_try_collection_insert_value (
    CDitto_t const * ditto,
    char const * coll_name,
    slice_ref_uint8_t doc_cbor,
    WriteStrategyRs_t write_strategy,
    char const * log_hint,
    CWriteTransaction_t * txn);

/** <No documentation available> */
dittoffi_result_bool_t
/* fn */ dittoffi_try_collection_remove (
    CDitto_t const * _ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    slice_ref_uint8_t id);

/** <No documentation available> */
dittoffi_result_slice_boxed_uint8_t
/* fn */ dittoffi_try_document_get_cbor_with_path_type (
    CDocument_t const * document,
    char const * pointer,
    PathAccessorType_t path_type);

/** \brief
 *  Execute specified DQL statement.
 *
 *  Returns a [`FfiQueryResult`], which contains a vector of [`FfiQueryResultItem`]s.
 *
 *  This is replacement for the old FFI, which was returning documents, but still uses the "old"
 *  style of FFI transaction API.
 *
 *  [`FfiQueryResult`]: crate::store::dql::response::FfiQueryResult
 *  [`FfiQueryResultItem`]: crate::store::dql::response::FfiQueryResultItem
 */
dittoffi_result_dittoffi_query_result_ptr_t
/* fn */ dittoffi_try_exec_statement (
    CDitto_t const * ditto,
    char const * statement,
    slice_ref_uint8_t args_cbor);

/** <No documentation available> */
typedef struct ChangeHandlerWithQueryResult {
    /** \brief
     *  Must be freed with `dittoffi_query_result_free`.
     */
    dittoffi_query_result_t * query_result;
} ChangeHandlerWithQueryResult_t;

/** <No documentation available> */
typedef struct dittoffi_result_int64 {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    int64_t success;
} dittoffi_result_int64_t;

/** <No documentation available> */
dittoffi_result_int64_t
/* fn */ dittoffi_try_experimental_register_change_observer_str (
    CDitto_t const * ditto,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    LiveQueryAvailability_t lq_availability,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*c_cb)(void *, ChangeHandlerWithQueryResult_t));

/** <No documentation available> */
dittoffi_result_uint64_t
/* fn */ dittoffi_try_queries_hash (
    CDitto_t const * ditto,
    slice_ref_char_const_ptr_t coll_names,
    slice_ref_char_const_ptr_t queries);

/** <No documentation available> */
typedef struct dittoffi_result_char_ptr {
    /** \brief
     *  Non-`NULL` pointer to opaque object on error, `NULL` otherwise.
     */
    dittoffi_error_t * error;

    /** \brief
     *  When no error occurred, the success value payload can be retrieved here.
     *
     *  Otherwise, the value is to be ignored.
     */
    char * success;
} dittoffi_result_char_ptr_t;

/** <No documentation available> */
dittoffi_result_char_ptr_t
/* fn */ dittoffi_try_queries_hash_mnemonic (
    CDitto_t const * ditto,
    slice_ref_char_const_ptr_t coll_names,
    slice_ref_char_const_ptr_t queries);

/** <No documentation available> */
dittoffi_result_int64_t
/* fn */ dittoffi_try_register_store_observer (
    CDitto_t const * ditto,
    char const * coll_name,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_by,
    int32_t limit,
    uint32_t offset,
    LiveQueryAvailability_t lq_availability,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*c_cb)(void *, c_cb_params_t));

/** <No documentation available> */
dittoffi_result_void_t
/* fn */ dittoffi_try_remove_subscription (
    CDitto_t const * ditto,
    char const * collection,
    char const * query,
    slice_ref_uint8_t query_args_cbor,
    slice_ref_COrderByParam_t order_by,
    int32_t limit,
    uint32_t offset);

/** \brief
 *  Removes a DQL sync subscription.
 *
 *  The arguments should be identical to the ones used during adding the subscription.
 *  Returns no meaningful value but for the resulting potential `.error`.
 */
dittoffi_result_void_t
/* fn */ dittoffi_try_remove_sync_subscription (
    CDitto_t const * ditto,
    char const * query,
    slice_ref_uint8_t query_args_cbor);

/** \brief
 *  Verify a base64 encoded license string.
 *
 *  # Parameters
 *  - `ditto`: The Ditto instance to activate.
 *  - `license`: A base64 encoded license string. This should be the output of
 *  `ditto_licenser::license_mgr::generate()`.
 */
dittoffi_result_void_t
/* fn */ dittoffi_try_verify_license (
    CDitto_t const * ditto,
    char const * license);


#ifdef __cplusplus
} /* extern \"C\" */
#endif

#endif /* __RUST_DITTOFFI__ */
