/*! \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_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"

/** \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_AwdlPlatformEvent TransportHandle_AwdlPlatformEvent_t;

/** \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;

/** \brief
 *  The platform advises Rust that a peer has changed its current connection
 *  status
 */
void
/* fn */ awdl_client_connect_state_changed (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    char const * announce,
    ConnectState_t state);

/** \brief
 *  The platform advises Rust that a complete message has been received from a
 *  remote peer
 */
void
/* fn */ awdl_client_data_available (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    char const * announce);

/** \brief
 *  The platform advises Rust that a peer has been identified. We know only its
 *  announce string.
 */
void
/* fn */ awdl_client_platform_peer_appeared (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    char const * announce);

/** \brief
 *  The platform advises Rust that a peer has disappeared.
 */
void
/* fn */ awdl_client_platform_peer_disappeared (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    char const * announce);

/** \brief
 *  The platform advises Rust that a given peer is now clear to queue up a new
 *  message whenever one is ready to go
 */
void
/* fn */ awdl_client_ready_to_send (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    char const * announce);

/** \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;

/** \brief
 *  The platform advises Rust that searching status changed
 */
void
/* fn */ awdl_client_scanning_state_changed (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    OnlineState_t state,
    TransportCondition_t condition);

/** \brief
 *  The platform advises Rust that advertising status changed
 */
void
/* fn */ awdl_server_advertising_state_changed (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    OnlineState_t state,
    TransportCondition_t condition);

/** \brief
 *  The platform advises Rust that a peer has changed its current connection
 *  status
 */
void
/* fn */ awdl_server_connect_state_changed (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    int64_t platform_id,
    ConnectState_t state);

/** \brief
 *  The platform advises Rust that a complete message has been received from a
 *  remote peer
 */
void
/* fn */ awdl_server_data_available (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    int64_t platform_id);

/** \brief
 *  The platform advises Rust that a peer has been identified. We know only its
 *  announce string.
 */
void
/* fn */ awdl_server_platform_peer_appeared (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    int64_t platform_id);

/** \brief
 *  The platform advises Rust that a peer has disappeared.
 */
void
/* fn */ awdl_server_platform_peer_disappeared (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    int64_t platform_id);

/** \brief
 *  The platform advises Rust that a given peer is now clear to queue up a new
 *  message whenever one is ready to go
 */
void
/* fn */ awdl_server_ready_to_send (
    TransportHandle_AwdlPlatformEvent_t const * handle,
    int64_t platform_id);

/** \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;

/** <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);

/** <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;

/** \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 AwdlClientCallbacks {
    /** <No documentation available> */
    void (*start_searching)(void *, char const *, char const *);

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

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

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

    /** <No documentation available> */
    int32_t (*send_data)(void *, char const *, slice_ref_uint8_t);

    /** <No documentation available> */
    int32_t (*read_data)(void *, char const *, slice_mut_uint8_t);
} AwdlClientCallbacks_t;

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

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

    /** <No documentation available> */
    void (*request_disconnect)(void *, int64_t);

    /** <No documentation available> */
    int32_t (*send_data)(void *, int64_t, slice_ref_uint8_t);

    /** <No documentation available> */
    int32_t (*read_data)(void *, int64_t, slice_mut_uint8_t);
} AwdlServerCallbacks_t;

/** <No documentation available> */
TransportHandle_AwdlPlatformEvent_t *
/* fn */ ditto_add_awdl_transport (
    CDitto_t const * ditto,
    AwdlClientCallbacks_t client_callbacks,
    void * client_ctx,
    AwdlServerCallbacks_t server_callbacks,
    void * server_ctx,
    void (*retain)(void *),
    void (*release)(void *));


#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;

/** <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 *));

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

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

    /** <No documentation available> */
    void (*resolve_service)(void *, slice_ref_uint8_t);
} MdnsClientCallbacks_t;

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

    /** <No documentation available> */
    void (*stop_advertising)(void *);
} MdnsServerCallbacks_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_MdnsPlatformEvent TransportHandle_MdnsPlatformEvent_t;

/** <No documentation available> */
TransportHandle_MdnsPlatformEvent_t *
/* fn */ ditto_add_mdns_discovery (
    CDitto_t const * ditto,
    MdnsClientCallbacks_t client_callbacks,
    MdnsServerCallbacks_t server_callbacks,
    void * 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 AWDL 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_awdl_transport_free_handle (
    TransportHandle_AwdlPlatformEvent_t * handle);

/** \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 v1 presence callback, releasing the receiver on the SDK side.
 */
void
/* fn */ ditto_clear_presence_v1_callback (
    CDitto_t const * ditto);

/** \brief
 *  Deregister v2 presence callback, releasing the receiver on the SDK side.
 */
void
/* fn */ ditto_clear_presence_v2_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);

/** \brief
 *  Retrieves last thread-local error message (used by some synchronous APIs)
 *  and retains ownership of it.
 *
 *  Returns `NULL` if there was no error. A non-null result MUST be freed using
 *  `ditto_c_string_free`.
 */
char *
/* fn */ ditto_error_message_peek (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.
 */
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_J_V_M_BASED,
    /** <No documentation available> */
    LANGUAGE_FLUTTER,
} 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);

/** \brief
 *  The SDK requests to drop its handle to the mDNS 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_mdns_transport_free_handle (
    TransportHandle_MdnsPlatformEvent_t * handle);

/** <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_v1 (
    CDitto_t const * ditto);

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

/** \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
 *  Register a function that will be called every time the connection state
 *  of remote peers changes.
 *  REMOVE THIS IN V4
 */
void
/* fn */ ditto_register_presence_v1_callback (
    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.
 *  REMOVE THIS IN V4
 */
void
/* fn */ ditto_register_presence_v2_callback (
    CDitto_t const * ditto,
    void * ctx,
    void (*retain)(void *),
    void (*release)(void *),
    void (*c_cb)(void *, char const *));

/** \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,
    /** <No documentation available> */
    DITTO_SDK_TRANSPORTS_ERROR_MISSING_LOCAL_NETWORK_INFO_PLIST_ENTRY = 5,
    /** <No documentation available> */
    DITTO_SDK_TRANSPORTS_ERROR_MISSING_BONJOUR_SERVICES_INFO_PLIST_ENTRY = 6,
} 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,
    char const * hostname,
    uint16_t port);

/** \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
 *  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> */
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);

/** <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);

/** \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);

/** \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);

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

/** <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
 *  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);

/** <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
 *
 *  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,
    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
 *
 *  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);

/** \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
 *  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
     *  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://docs.ditto.live/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
     *  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
     *  Attempted to use a Ditto feature after closing Ditto.
     *  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 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);

/** \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
 *  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);

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

/** <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_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;

/** <No documentation available> */
void
/* fn */ dittoffi_query_result_free (
    dittoffi_query_result_t * 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);

/** \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
 *  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
 *  Free a Vec of [`FfiStoreObserver`]
 */
void
/* fn */ dittoffi_store_observer_free_sparse (
    Vec_dittoffi_store_observer_ptr_t _vec);

/** \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 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 DQL query string of the given observer.
 */
char *
/* fn */ dittoffi_store_observer_query_string (
    dittoffi_store_observer_t const * observer);

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

/** \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;

/** <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,
    BoxDynFnMut2_void_dittoffi_query_result_ptr_ArcDynFn0_void_t callback);

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

/** \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 DQL arguments object associated with the given sync subscription, if one exists.
 */
slice_boxed_uint8_t
/* fn */ dittoffi_sync_subscription_query_arguments (
    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 v);

/** \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);

/** <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);

/** <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
 *  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> */
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_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_Vec_slice_boxed_uint8_t
/* fn */ dittoffi_try_collection_remove_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_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);

/** <No documentation available> */
dittoffi_result_void_t
/* fn */ dittoffi_try_collection_update (
    CDitto_t const * _ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    CDocument_t * document);

/** <No documentation available> */
dittoffi_result_void_t
/* fn */ dittoffi_try_collection_update_multiple (
    CDitto_t const * _ditto,
    char const * coll_name,
    CWriteTransaction_t * transaction,
    Vec_CDocument_ptr_t documents);

/** <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> */
typedef struct dittoffi_result_Vec_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.
     */
    Vec_char_ptr_t success;
} dittoffi_result_Vec_char_ptr_t;

/** <No documentation available> */
dittoffi_result_Vec_char_ptr_t
/* fn */ dittoffi_try_get_collection_names (
    CDitto_t const * ditto);

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

/** <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);

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

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

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

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

/** \brief
 *  The platform advises Rust that the TCP listener will need to be restarted.
 */
void
/* fn */ mdns_server_invalidate_listener (
    TransportHandle_MdnsPlatformEvent_t const * handle);

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

/** \brief
 *  The platform advises Rust that we have resolved a peer's hostname and port
 */
void
/* fn */ mdns_service_did_resolve (
    TransportHandle_MdnsPlatformEvent_t const * handle,
    char const * announce_string,
    char const * hostname,
    uint16_t port);


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

#endif /* __RUST_DITTOFFI__ */
