~ehmry/nim_tox

008aff38d733c2c1f89fea378dcb7f42bce6eb08 — Emery Hemingway 2 months ago c67b7e6 v0.2.0
Use Tox header for all imports, especially enums

Passing Nim enum pointers to the C library was trashing the stack.
5 files changed, 186 insertions(+), 172 deletions(-)

M src/toxcore.nim
M tests/node.nim
M tests/simple.nim
M tests/test1.nim
M toxcore.nimble
M src/toxcore.nim => src/toxcore.nim +175 -164
@@ 23,8 23,10 @@ import std/strutils
{.passC: staticExec("pkg-config --cflags toxcore").}
{.passL: staticExec("pkg-config --libs toxcore").}

{.pragma: ctoxProc, importc: "tox_$1".}
{.pragma: ctoxCallbackProc, importc: "tox_callback_$1".}
{.pragma: ctoxHeader, header: "tox/tox.h".}
{.pragma: ctoxEnum, ctoxHeader, importc: "Tox_$1".}
{.pragma: ctoxProc, ctoxHeader, importc: "tox_$1".}
{.pragma: ctoxCallbackProc, ctoxHeader, importc: "tox_callback_$1".}

type ToxError* = object of CatchableError



@@ 60,6 62,13 @@ const # Values converted from tox.h defines
  TOX_MAX_FILENAME_LENGTH = 255
  TOX_MAX_HOSTNAME_LENGTH = 255

func version_major*(): uint32 {.ctoxProc.}
func version_minor*(): uint32 {.ctoxProc.}
func version_patch*(): uint32 {.ctoxProc.}
func version_is_compatible*(major, minor, patch: uint32): bool {.ctoxProc.}
func version_is_compatible*(): bool {.importc:
  "TOX_VERSION_IS_ABI_COMPATIBLE", ctoxHeader.}

func public_key_size(): uint32 {.ctoxProc.}
func secret_key_size(): uint32 {.ctoxProc.}
func conference_uid_size(): uint32 {.ctoxProc.}


@@ 141,36 150,36 @@ toxIndexType Conference
toxIndexType Peer

type
  TOX_CONNECTION* = enum
  Connection* {.ctoxEnum.} = enum
    ## Connection state.
    TOX_CONNECTION_NONE,
    TOX_CONNECTION_TCP,
    TOX_CONNECTION_UDP

  TOX_USER_STATUS* = enum
  User_Status* {.ctoxEnum.} = enum
    ## User status.
    TOX_USER_STATUS_NONE,
    TOX_USER_STATUS_AWAY,
    TOX_USER_STATUS_BUSY

  TOX_MESSAGE_TYPE* = enum
  Message_Type* {.ctoxEnum.} = enum
    ## Application message type.
    TOX_MESSAGE_TYPE_NORMAL,
    TOX_MESSAGE_TYPE_ACTION

  TOX_PROXY_TYPE* = enum
  Proxy_Type* {.ctoxEnum.} = enum
    ## Connection proxy method.
    TOX_PROXY_TYPE_NONE,
    TOX_PROXY_TYPE_HTTP,
    TOX_PROXY_TYPE_SOCKS5

  TOX_SAVEDATA_TYPE* = enum
  Savedata_Type* {.ctoxEnum.} = enum
    ## Format of save data.
    TOX_SAVEDATA_TYPE_NONE,
    TOX_SAVEDATA_TYPE_TOX_SAVE,
    TOX_SAVEDATA_TYPE_SECRET_KEY

  TOX_LOG_LEVEL* = enum
  Log_Level* {.ctoxEnum.} = enum
    ## Logging level.
    TOX_LOG_LEVEL_TRACE,
    TOX_LOG_LEVEL_DEBUG,


@@ 178,18 187,18 @@ type
    TOX_LOG_LEVEL_WARNING,
    TOX_LOG_LEVEL_ERROR

  TOX_FILE_KIND* = enum
  File_Kind* {.ctoxEnum.} = enum
    ## File transfer type.
    TOX_FILE_KIND_DATA,
    TOX_FILE_KIND_AVATAR

  TOX_FILE_CONTROL* = enum
  File_Control* {.ctoxEnum.} = enum
    ## File transfer control command.
    TOX_FILE_CONTROL_RESUME,
    TOX_FILE_CONTROL_PAUSE,
    TOX_FILE_CONTROL_CANCEL

  TOX_CONFERENCE_TYPE* = enum
  Conference_Type* {.ctoxEnum.} = enum
    ## Conference type.
    TOX_CONFERENCE_TYPE_TEXT,
    TOX_CONFERENCE_TYPE_AV


@@ 199,21 208,21 @@ type
    ## Opaque C type wrapped by the `Tox` object.

  tox_log_cb* = proc (
    core: Core; level: TOX_LOG_LEVEL; file: cstring; line: uint32;
    core: Core; level: Log_Level; file: cstring; line: uint32;
    `func`: cstring; message: cstring; user_data: pointer) {.cdecl.}
    ## Logging callback type invoked directly by C library.

  CbSelfConnectionStatus* = proc (
    status: TOX_CONNECTION) {.closure, gcsafe.}
    status: Connection) {.closure, gcsafe.}

  CbFriendName* = proc (
    friend: Friend; name: string) {.gcsafe.}
  CbFriendStatusMessage* = proc (
    friend: Friend; msg: string) {.gcsafe.}
  CbFriendStatus* = proc (
    friend: Friend; status: TOX_USER_STATUS) {.gcsafe.}
    friend: Friend; status: UserStatus) {.gcsafe.}
  CbFriendConnectionStatus* = proc (
    friend: Friend; status: TOX_CONNECTION) {.gcsafe.}
    friend: Friend; status: Connection) {.gcsafe.}
  CbFriendTyping* = proc (
    friend: Friend; typing: bool) {.gcsafe.}
  CbFriendReadReceipt* = proc (


@@ 221,10 230,10 @@ type
  CbFriendRequest* = proc (
    key: PublicKey; msg: string) {.gcsafe.}
  CbFriendMessage* = proc (
    friend: Friend; msg: string; kind: TOX_MESSAGE_TYPE) {.gcsafe.}
    friend: Friend; msg: string; kind: MessageType) {.gcsafe.}

  CbFileRecvControl* = proc (
    friend: Friend; file: FileTransfer; control: TOX_FILE_CONTROL) {.gcsafe.}
    friend: Friend; file: FileTransfer; control: FileControl) {.gcsafe.}
  CbFileChunkRequest* = proc (
    friend: Friend; file: FileTransfer; pos: uint64; size: int) {.gcsafe.}
  CbFileRecv* = proc (


@@ 235,11 244,11 @@ type
        size: int) {.gcsafe.}

  CbConferenceInvite* = proc (
    friend: Friend; kind: TOX_CONFERENCE_TYPE; cookie: string) {.gcsafe.}
    friend: Friend; kind: ConferenceType; cookie: string) {.gcsafe.}
  CbConferenceConnected* = proc (
    conf: Conference) {.gcsafe.}
  CbConferenceMessage* = proc (
    conf: Conference; peer: Peer; kind: TOX_MESSAGE_TYPE; msg: string) {.gcsafe.}
    conf: Conference; peer: Peer; kind: MessageType; msg: string) {.gcsafe.}
  CbConferenceTitle* = proc (
    conf: Conference; peer: Peer; title: string) {.gcsafe.}
  CbConferencePeerName* = proc (


@@ 277,83 286,84 @@ type
    friendLosslessPacket: CbFriendLosslessPacket

type
  Options* = distinct pointer
  Tox_Options {.pure, importc: "struct Tox_Options".} = object
  Options* = ptr Tox_Options
    ## Object for initializing a Tox instance.

{.pragma: ctox_options, importc: "tox_options_$1".}
{.pragma: ctox_options_get, importc: "tox_options_get_$1".}
{.pragma: ctox_options, importc: "tox_options_$1", ctoxHeader.}
{.pragma: ctox_options_get, importc: "tox_options_get_$1", ctoxHeader.}

proc ipv6_enabled*(options: Options): bool {.ctox_options_get.}
proc `ipv6_enabled=`*(options: Options; ipv6_enabled: bool) {.
  importc: "tox_options_set_ipv6_enabled".}
  importc: "tox_options_set_ipv6_enabled", ctoxHeader.}

proc udp_enabled*(options: Options): bool {.ctox_options_get.}
proc `udp_enabled=`*(options: Options; udp_enabled: bool) {.
  importc: "tox_options_set_udp_enabled".}
  importc: "tox_options_set_udp_enabled", ctoxHeader.}

proc local_discovery_enabled*(options: Options): bool {.ctox_options_get.}
proc `local_discovery_enabled=`*(options: Options;
    local_discovery_enabled: bool) {.
  importc: "tox_options_set_local_discovery_enabled".}
  importc: "tox_options_set_local_discovery_enabled", ctoxHeader, ctoxHeader.}

proc proxy_type*(options: Options): TOX_PROXY_TYPE {.ctox_options_get.}
proc `proxy_type=`*(options: Options; `type`: TOX_PROXY_TYPE) {.
  importc: "tox_options_set_proxy_type".}
proc proxy_type*(options: Options): ProxyType {.ctox_options_get.}
proc `proxy_type=`*(options: Options; `type`: ProxyType) {.
  importc: "tox_options_set_proxy_type", ctoxHeader.}

proc proxy_host*(options: Options): cstring {.ctox_options_get.}
proc `proxy_host=`*(options: Options; host: cstring) {.
  importc: "tox_options_set_proxy_host".}
  importc: "tox_options_set_proxy_host", ctoxHeader.}

proc proxy_port*(options: Options): uint16 {.ctox_options_get.}
proc `proxy_port=`*(options: Options; port: uint16) {.
  importc: "tox_options_set_proxy_port".}
  importc: "tox_options_set_proxy_port", ctoxHeader.}

proc start_port*(options: Options): uint16 {.ctox_options_get.}
proc `start_port=`*(options: Options; start_port: uint16) {.
  importc: "tox_options_set_start_port".}
  importc: "tox_options_set_start_port", ctoxHeader.}

proc end_port*(options: Options): uint16 {.ctox_options_get.}
proc `end_port=`*(options: Options; end_port: uint16) {.
  importc: "tox_options_set_end_port".}
  importc: "tox_options_set_end_port", ctoxHeader.}

proc tcp_port*(options: Options): uint16 {.ctox_options_get.}
proc `tcp_port=`*(options: Options; tcp_port: uint16) {.
  importc: "tox_options_set_tcp_port".}
  importc: "tox_options_set_tcp_port", ctoxHeader.}

proc hole_punching_enabled*(options: Options): bool {.ctox_options_get.}
proc `hole_punching_enabled=`*(options: Options; hole_punching_enabled: bool) {.
  importc: "tox_options_set_hole_punching_enabled".}
  importc: "tox_options_set_hole_punching_enabled", ctoxHeader.}

proc savedata_type*(options: Options): TOX_SAVEDATA_TYPE {.ctox_options_get.}
proc `savedata_type=`*(options: Options; `type`: TOX_SAVEDATA_TYPE) {.
  importc: "tox_options_set_savedata_type".}
proc savedata_type*(options: Options): SavedataType {.ctox_options_get.}
proc `savedata_type=`*(options: Options; `type`: SavedataType) {.
  importc: "tox_options_set_savedata_type", ctoxHeader.}

proc savedata_data*(options: Options): ptr uint8 {.ctox_options_get.}
proc savedata_length*(options: Options): csize {.ctox_options_get.}

proc `saveData=`*(options: Options; data: string) =
  proc options_set_savedata_data(options: Options; data: cstring;
      length: csize) {.ctoxProc.}
  # proc options_set_savedata_length(options: Options; length: csize) {.ctoxProc.}
      length: csize) {.ctoxProc, ctoxHeader.}
  # proc options_set_savedata_length(options: Options; length: csize) {.ctoxProc, ctoxHeader.}
  options.options_set_savedata_data(data, data.len)

proc log_callback*(options: Options): tox_log_cb {.ctox_options_get.}
proc `log_callback=`*(options: Options; callback: tox_log_cb) {.
  importc: "tox_options_set_log_callback".}
  importc: "tox_options_set_log_callback", ctoxHeader.}
  ## Install a logging callback within the C Tox core. This callback
  ## must have C calling convention and thus annotated with the
  ## {.cdecl.} pragma.
  ## {.cdecl, ctoxHeader.} pragma.

proc log_user_data*(options: Options): pointer {.ctox_options_get.}
proc `log_user_data=`*(options: Options; user_data: pointer) {.
  importc: "tox_options_set_log_user_data".}
  importc: "tox_options_set_log_user_data", ctoxHeader.}
  ## Set state object passed to logging callback.

type
  Tox_Err_Options_New = enum
  Err_Options_New {.ctoxEnum.} = enum
    TOX_ERR_OPTIONS_NEW_OK,
    TOX_ERR_OPTIONS_NEW_MALLOC
  Tox_Err_New = enum
  Err_New {.ctoxEnum.} = enum
    TOX_ERR_NEW_OK,
    TOX_ERR_NEW_NULL,
    TOX_ERR_NEW_MALLOC,


@@ 365,6 375,9 @@ type
    TOX_ERR_NEW_LOAD_ENCRYPTED,
    TOX_ERR_NEW_LOAD_BAD_FORMAT

proc tox_new(options: Options; error: ptr Err_New): Core {.
  importc, ctoxHeader.}

proc newTox*(configure: proc (opt: Options)): Tox =
  ## Create a new Tox instance.
  ##


@@ 374,26 387,24 @@ proc newTox*(configure: proc (opt: Options)): Tox =
  ##     opts.holePunchingEnabled = false
  ##  tox.iterate()
  ##
  proc options_new(error: ptr TOX_ERR_OPTIONS_NEW): Options {.ctoxProc.}
  proc options_new(error: ptr ERR_OPTIONS_NEW): Options {.ctoxProc.}
  proc options_default(options: Options) {.ctoxProc.}
  proc options_free(options: Options) {.ctoxProc.}
  proc new(options: Options; error: ptr TOX_ERR_NEW): Core {.ctoxProc.}
  var err: TOX_ERR_OPTIONS_NEW
  var err: ERR_OPTIONS_NEW
  let opt = options_new(addr err)
  ctoxAssert(TOX_ERR_OPTIONS_NEW_OK, err)
  defer: options_free(opt)
  options_default(opt)
  configure(opt)
  block:
    var err: TOX_ERR_NEW
    result = Tox(core: new(opt, addr err))
    var err: ERR_NEW
    result = Tox(core: tox_new(opt, addr err))
    ctoxAssert(TOX_ERR_NEW_OK, err)

proc newTox*(): Tox =
  ## Create a new Tox instance.
  proc new(options: Options; error: ptr TOX_ERR_NEW): Core {.ctoxProc.}
  var err: TOX_ERR_NEW
  result = Tox(core: new(nil, addr err))
  var err: ERR_NEW
  result = Tox(core: tox_new(nil, addr err))
  ctoxAssert(TOX_ERR_NEW_OK, err)

proc close*(tox: Tox) {.tags: [IOEffect].} =


@@ 418,7 429,7 @@ proc saveData*(tox: Tox): string =
    tox.core.get_savedata(addr result[0])

type
  Tox_Err_Bootstrap = enum
  Err_Bootstrap {.ctoxEnum.} = enum
    TOX_ERR_BOOTSTRAP_OK,
    TOX_ERR_BOOTSTRAP_NULL,
    TOX_ERR_BOOTSTRAP_BAD_HOST,


@@ 432,7 443,7 @@ proc bootstrap*(tox: Tox; host: string; key: PublicKey; port = defaultPort) {.
  ## Bootstap the `tox` DHT state.
  proc bootstrap(
    core: Core; host: cstring; port: uint16;
    public_key: ptr uint8; error: ptr Tox_Err_Bootstrap): bool {.ctoxProc.}
    public_key: ptr uint8; error: ptr Err_Bootstrap): bool {.ctoxProc.}
  var err = TOX_ERR_BOOTSTRAP_OK
  discard bootstrap(tox.core, host, port, unsafeAddr key.bytes[0], addr err)
  ctoxAssert(TOX_ERR_BOOTSTRAP_OK, err)


@@ 441,7 452,7 @@ proc addTcpRelay*(tox: Tox; host: string; port: uint16; key: PublicKey) =
  ## Add a TCP relay to `tox`.
  proc add_tcp_relay(
    core: Core; host: cstring; port: uint16;
    public_key: ptr uint8; error: ptr Tox_Err_Bootstrap): bool {.ctoxProc.}
    public_key: ptr uint8; error: ptr Err_Bootstrap): bool {.ctoxProc.}
  var err = TOX_ERR_BOOTSTRAP_OK
  discard tox.core.add_tcp_relay(host, port, unsafeAddr key.bytes[0], addr err)
  ctoxAssert(TOX_ERR_BOOTSTRAP_OK, err)


@@ 461,8 472,8 @@ template callbackSetter(name, body: untyped) =
callbackSetter self_connection_status:
  ## Install a callback for handling the instance connection state.
  type cbType = proc (
    core: Core; connection_status: TOX_CONNECTION; user_data: pointer) {.cdecl.}
  proc wrapper(core: Core; status: TOX_CONNECTION; user_data: pointer) {.cdecl.} =
    core: Core; connection_status: Connection; user_data: pointer) {.cdecl.}
  proc wrapper(core: Core; status: Connection; user_data: pointer) {.cdecl.} =
    callThru(status)

proc iteration_interval*(tox: Tox): int =


@@ 510,7 521,7 @@ proc secretKey*(tox: Tox): SecretKey =
  tox.core.self_get_secret_key(addr result.bytes[0])

type
  Tox_Err_Set_Info = enum
  Err_Set_Info {.ctoxEnum.} = enum
    TOX_ERR_SET_INFO_OK,
    TOX_ERR_SET_INFO_NULL,
    TOX_ERR_SET_INFO_TOO_LONG


@@ 519,7 530,7 @@ proc `name=`*(tox: Tox; name: string) {.tags: [IOEffect].} =
  ## Set the display name of `tox` instance and propagate it to friends.
  proc self_set_name(
    core: Core; name: cstring; length: csize;
    error: ptr Tox_Err_Set_Info): bool {.ctoxProc.}
    error: ptr Err_Set_Info): bool {.ctoxProc.}
  var err = TOX_ERR_SET_INFO_OK
  discard tox.core.self_set_name(name, name.len, nil)
  ctoxAssert(TOX_ERR_SET_INFO_OK, err)


@@ 536,7 547,7 @@ proc `statusMessage=`*(tox: Tox; msg: string) {.tags: [IOEffect].} =
  ## Set the status message of `tox` instance and propagate it to friends.
  proc self_set_status_message(
    core: Core; status_message: cstring;
    length: csize; error: ptr Tox_Err_Set_Info): bool {.ctoxProc.}
    length: csize; error: ptr Err_Set_Info): bool {.ctoxProc.}
  var err = TOX_ERR_SET_INFO_OK
  discard tox.core.self_set_status_message(msg, msg.len, addr err)
  ctoxAssert(TOX_ERR_SET_INFO_OK, err)


@@ 549,17 560,17 @@ proc statusMessage*(tox: Tox): string {.tags: [IOEffect].} =
  if 0 < result.len:
    tox.core.self_get_status_message(addr result[0])

proc `status=`*(tox: Tox; status: TOX_USER_STATUS) {.tags: [IOEffect].} =
proc `status=`*(tox: Tox; status: UserStatus) {.tags: [IOEffect].} =
  ## Set the status of `tox` instance.
  proc self_set_status(core: Core; status: TOX_USER_STATUS) {.ctoxProc.}
  proc self_set_status(core: Core; status: UserStatus) {.ctoxProc.}
  tox.core.self_set_status(status)

proc status*(tox: Tox): TOX_USER_STATUS =
proc status*(tox: Tox): UserStatus =
  ## Retrieve the status of `tox` instance.
  proc self_get_status(core: Core): TOX_USER_STATUS {.ctoxProc.}
  proc self_get_status(core: Core): UserStatus {.ctoxProc.}
  tox.core.self_get_status()

type Tox_Err_Friend_Add = enum
type Err_Friend_Add {.ctoxEnum.} = enum
  TOX_ERR_FRIEND_ADD_OK,
  TOX_ERR_FRIEND_ADD_NULL,
  TOX_ERR_FRIEND_ADD_TOO_LONG,


@@ 574,7 585,7 @@ proc addFriend*(tox: Tox; id: Address; msg: string): Friend {.tags: [IOEffect].}
  ## Issue a friend request and return a token for the pending friend.
  proc friend_add(
    core: Core; address: ptr uint8; message: cstring;
    length: csize; error: ptr TOX_ERR_FRIEND_ADD): Friend {.ctoxProc.}
    length: csize; error: ptr ERR_FRIEND_ADD): Friend {.ctoxProc.}
  var err = TOX_ERR_FRIEND_ADD_OK
  result = tox.core.friend_add(unsafeAddr id.bytes[0], msg, msg.len, addr err)
  ctoxAssert(TOX_ERR_FRIEND_ADD_OK, err)


@@ 583,14 594,14 @@ proc addFriendNoRequest*(tox: Tox; key: PublicKey): Friend {.tags: [IOEffect].} 
  ## Respond to a friend request and return a token for the new friend.
  proc friend_add_norequest(
    core: Core; public_key: ptr uint8;
    error: ptr TOX_ERR_FRIEND_ADD): Friend {.ctoxProc.}
    error: ptr ERR_FRIEND_ADD): Friend {.ctoxProc.}
  var err = TOX_ERR_FRIEND_ADD_OK
  result = tox.core.friend_add_norequest(
    unsafeAddr key.bytes[0], addr err)
  ctoxAssert(TOX_ERR_FRIEND_ADD_OK, err)

type
  Tox_Err_Friend_Delete = enum
  Err_Friend_Delete {.ctoxEnum.} = enum
    TOX_ERR_FRIEND_DELETE_OK,
    TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND



@@ 598,12 609,12 @@ proc delete*(tox: Tox; friend: Friend): bool {.tags: [IOEffect].} =
  ## Revoke a friend.
  proc friend_delete(
    core: Core; friend: Friend;
    error: ptr Tox_Err_Friend_Delete): bool {.ctoxProc.}
    error: ptr Err_Friend_Delete): bool {.ctoxProc.}
  var err = TOX_ERR_FRIEND_DELETE_OK
  discard tox.core.friend_delete(friend, addr err)
  ctoxAssert(TOX_ERR_FRIEND_DELETE_OK, err)

type Tox_Err_Friend_By_Public_Key = enum
type Err_Friend_By_Public_Key {.ctoxEnum.} = enum
  TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK,
  TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL,
  TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND


@@ 612,7 623,7 @@ proc friend*(tox: Tox; key: PublicKey): Friend =
  ## Retrieve a friend handle by public key.
  proc friend_by_public_key(
    core: Core; public_key: ptr uint8;
    error: ptr Tox_Err_Friend_By_Public_Key): Friend {.ctoxProc.}
    error: ptr Err_Friend_By_Public_Key): Friend {.ctoxProc.}
  var err = TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK
  result = tox.core.friend_by_public_key(unsafeAddr key.bytes[0], addr err)
  ctoxAssert(TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK, err)


@@ 630,7 641,7 @@ proc friends*(tox: Tox): seq[Friend] =
  if 0 < result.len:
    tox.core.self_get_friend_list(addr result[0])

type Tox_Err_Friend_Get_Public_Key = enum
type Err_Friend_Get_Public_Key {.ctoxEnum.} = enum
  TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK,
  TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND



@@ 639,12 650,12 @@ proc publicKey*(tox: Tox; friend: Friend): PublicKey =
  proc friend_get_public_key(
    core: Core; friend: Friend;
    public_key: ptr uint8;
    error: ptr Tox_Err_Friend_Get_Public_Key): bool {.ctoxProc.}
    error: ptr Err_Friend_Get_Public_Key): bool {.ctoxProc.}
  var err = TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK
  discard tox.core.friend_get_public_key(friend, addr result.bytes[0], addr err)
  ctoxAssert(TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK, err)

type Tox_Err_Friend_Get_Last_Online = enum
type Err_Friend_Get_Last_Online {.ctoxEnum.} = enum
  TOX_ERR_FRIEND_GET_LAST_ONLINE_OK,
  TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND



@@ 652,12 663,12 @@ proc lastOnline*(tox: Tox; friend: Friend): uint64 =
  ## Retrieve the last time a friend was known to be online in Unix epoch time.
  proc friend_get_last_online(
    core: Core; friend: Friend;
    error: ptr Tox_Err_Friend_Get_Last_Online): uint64 {.ctoxProc.}
    error: ptr Err_Friend_Get_Last_Online): uint64 {.ctoxProc.}
  var err = TOX_ERR_FRIEND_GET_LAST_ONLINE_OK
  result = tox.core.friend_get_last_online(friend, addr err)
  ctoxAssert(TOX_ERR_FRIEND_GET_LAST_ONLINE_OK, err)

type Tox_Err_Friend_Query = enum
type Err_Friend_Query {.ctoxEnum.} = enum
  TOX_ERR_FRIEND_QUERY_OK,
  TOX_ERR_FRIEND_QUERY_NULL,
  TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND


@@ 666,10 677,10 @@ proc name*(tox: Tox; friend: Friend): string =
  ## Retrieve the name of a friend by handle.
  proc friend_get_name_size(
    core: Core; friend: Friend;
    error: ptr Tox_Err_Friend_Query): csize {.ctoxProc.}
    error: ptr Err_Friend_Query): csize {.ctoxProc.}
  proc friend_get_name(
    core: Core; friend: Friend; name: ptr char;
    error: ptr Tox_Err_Friend_Query): bool {.ctoxProc.}
    error: ptr Err_Friend_Query): bool {.ctoxProc.}
  var err = TOX_ERR_FRIEND_QUERY_OK
  result = newString(tox.core.friend_get_name_size(friend, addr err))
  ctoxAssert(TOX_ERR_FRIEND_QUERY_OK, err)


@@ 691,11 702,11 @@ proc statusMessage*(tox: Tox; friend: Friend): string =
  ## Retrieve the status message of a friend.
  proc friend_get_status_message_size(
    core: Core; friend: Friend;
    error: ptr Tox_Err_Friend_Query): csize {.ctoxProc.}
    error: ptr Err_Friend_Query): csize {.ctoxProc.}
  proc friend_get_status_message(
    core: Core; friend: Friend;
    status_message: ptr char;
    error: ptr Tox_Err_Friend_Query): bool {.ctoxProc.}
    error: ptr Err_Friend_Query): bool {.ctoxProc.}
  var err = TOX_ERR_FRIEND_QUERY_OK
  result = newString(tox.core.friend_get_status_message_size(friend, addr err))
  ctoxAssert(TOX_ERR_FRIEND_QUERY_OK, err)


@@ 715,12 726,12 @@ callbackSetter friend_status_message:
      user_data: pointer) {.cdecl.} =
    callThru(friend, ctoxString(message, length))

proc status*(tox: Tox; friend: Friend): TOX_USER_STATUS =
proc status*(tox: Tox; friend: Friend): UserStatus =
  ## Retrieve the status of a friend.
  proc friend_get_status(
    core: Core; friend: Friend;
    error: ptr Tox_Err_Friend_Query): TOX_USER_STATUS {.ctoxProc.}
  var err: Tox_Err_Friend_Query
    error: ptr Err_Friend_Query): UserStatus {.ctoxProc.}
  var err: Err_Friend_Query
  result = tox.core.friend_get_status(friend, addr err)
  ctoxAssert(TOX_ERR_FRIEND_QUERY_OK, err)



@@ 728,17 739,17 @@ callbackSetter friend_status:
  ## Install a callback for friend statuses.
  type cbType = proc (
    core: Core; friend: Friend;
    status: TOX_USER_STATUS; user_data: pointer) {.cdecl.}
    status: UserStatus; user_data: pointer) {.cdecl.}
  proc wrapper(
      core: Core; friend: Friend;
      status: TOX_USER_STATUS; user_data: pointer) {.cdecl.} =
      status: UserStatus; user_data: pointer) {.cdecl.} =
    callThru(friend, status)

proc connectionStatus*(tox: Tox; friend: Friend): TOX_CONNECTION =
proc connectionStatus*(tox: Tox; friend: Friend): Connection =
  ## Retrieve the connection status of a friend.
  proc friend_get_connection_status(
    core: Core; friend: Friend;
    error: ptr Tox_Err_Friend_Query): TOX_CONNECTION {.ctoxProc.}
    error: ptr Err_Friend_Query): Connection {.ctoxProc.}
  var err = TOX_ERR_FRIEND_QUERY_OK
  result = tox.core.friend_get_connection_status(friend, addr err)
  ctoxAssert(TOX_ERR_FRIEND_QUERY_OK, err)


@@ 747,11 758,11 @@ callbackSetter friend_connection_status:
  ## Install a callback for friend connection statuses.
  type cbType = proc (
    core: Core; friend: Friend;
    connection_status: TOX_CONNECTION;
    connection_status: Connection;
    user_data: pointer) {.cdecl.}
  proc wrapper(
      core: Core; friend: Friend;
      status: TOX_CONNECTION;
      status: Connection;
      user_data: pointer) {.cdecl.} =
    callThru(friend, status)



@@ 759,7 770,7 @@ proc typing*(tox: Tox; friend: Friend): bool =
  ## Retrieve the typing status of a friend.
  proc friend_get_typing(
    core: Core; friend: Friend;
    error: ptr Tox_Err_Friend_Query): bool {.ctoxProc.}
    error: ptr Err_Friend_Query): bool {.ctoxProc.}
  var err = TOX_ERR_FRIEND_QUERY_OK
  result = tox.core.friend_get_typing(friend, addr err)
  ctoxAssert(TOX_ERR_FRIEND_QUERY_OK, err)


@@ 777,7 788,7 @@ callbackSetter friend_typing:
      tox.friendTyping(friend, is_typing)

type
  Tox_Err_Set_Typing* = enum
  Err_Set_Typing* {.ctoxEnum.} = enum
    TOX_ERR_SET_TYPING_OK,
    TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND



@@ 785,12 796,12 @@ proc typing*(tox: Tox; friend: Friend; typing: bool) {.tags: [IOEffect].} =
  ## Set the typing status of `tox` instance.
  proc self_set_typing(
    core: Core; friend: Friend; typing: bool;
    error: ptr Tox_Err_Set_Typing): bool {.ctoxProc.}
    error: ptr Err_Set_Typing): bool {.ctoxProc.}
  var err = TOX_ERR_SET_TYPING_OK
  discard tox.core.self_set_typing(friend, typing, addr err)
  ctoxAssert(TOX_ERR_SET_TYPING_OK, err)

type Tox_Err_Friend_Send_Message = enum
type Err_Friend_Send_Message {.ctoxEnum.} = enum
  TOX_ERR_FRIEND_SEND_MESSAGE_OK,
  TOX_ERR_FRIEND_SEND_MESSAGE_NULL,
  TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND,


@@ 804,8 815,8 @@ proc send*(tox: Tox; friend: Friend; msg: string;
  ## Send a message to a friend.
  proc friend_send_message(
    core: Core; friend: Friend;
    kind: TOX_MESSAGE_TYPE; message: cstring;
    length: csize; error: ptr TOX_ERR_FRIEND_SEND_MESSAGE): MessageId {.ctoxProc.}
    kind: MessageType; message: cstring;
    length: csize; error: ptr ERR_FRIEND_SEND_MESSAGE): MessageId {.ctoxProc.}
  var err = TOX_ERR_FRIEND_SEND_MESSAGE_OK
  result = tox.core.friend_send_message(friend, kind, msg, msg.len, addr err)
  ctoxAssert(TOX_ERR_FRIEND_SEND_MESSAGE_OK, err)


@@ 837,11 848,11 @@ callbackSetter friend_message:
  ## Install a callback for friend messages.
  type cbType = proc (
    core: Core; friend: Friend;
    kind: TOX_MESSAGE_TYPE; message: ptr uint8;
    kind: MessageType; message: ptr uint8;
    length: csize; user_data: pointer) {.cdecl.}
  proc wrapper(
      core: Core; friend: Friend;
      kind: TOX_MESSAGE_TYPE; message: ptr uint8;
      kind: MessageType; message: ptr uint8;
      length: csize; user_data: pointer) {.cdecl.} =
    callThru(friend, ctoxString(message, length), kind)



@@ 851,7 862,7 @@ proc hash*(data: pointer; size: int): Hash =
  proc hash(hash: ptr uint8; data: pointer; length: csize): bool {.ctoxProc.}
  discard hash(addr result.bytes[0], data, size)

type Tox_Err_File_Control = enum
type Err_File_Control {.ctoxEnum.} = enum
  TOX_ERR_FILE_CONTROL_OK,
  TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND,
  TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED,


@@ 862,27 873,27 @@ type Tox_Err_File_Control = enum
  TOX_ERR_FILE_CONTROL_SENDQ

proc control*(tox: Tox; friend: Friend; file: FileTransfer;
    control: TOX_FILE_CONTROL) {.tags: [IOEffect].} =
    control: FileControl) {.tags: [IOEffect].} =
  proc file_control(
    core: Core; friend: Friend; file: FileTransfer;
    control: TOX_FILE_CONTROL;
    error: ptr TOX_ERR_FILE_CONTROL): bool {.ctoxProc.}
  var err: Tox_Err_File_Control
    control: FileControl;
    error: ptr ERR_FILE_CONTROL): bool {.ctoxProc.}
  var err: Err_File_Control
  discard tox.core.file_control(friend, file, control, addr err)
  ctoxAssert(TOX_ERR_FILE_CONTROL_OK, err)

callbackSetter file_recv_control:
  type cbType = proc (
    core: Core; friend: Friend;
    file: FileTransfer; control: TOX_FILE_CONTROL;
    file: FileTransfer; control: FileControl;
    user_data: pointer) {.cdecl.}
  proc wrapper(
      core: Core; friend: Friend;
      file: FileTransfer; control: TOX_FILE_CONTROL;
      file: FileTransfer; control: FileControl;
      user_data: pointer) {.cdecl.} =
    callThru(friend, file, control)

type Tox_Err_File_Seek = enum
type Err_File_Seek {.ctoxEnum.} = enum
  TOX_ERR_FILE_SEEK_OK,
  TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND,
  TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED,


@@ 894,12 905,12 @@ type Tox_Err_File_Seek = enum
proc seek*(tox: Tox; friend: Friend; file: FileTransfer; pos: uint64) {.tags: [IOEffect].} =
  proc file_seek(
    core: Core; friend: Friend; file: FileTransfer;
    position: uint64; error: ptr Tox_Err_File_Seek): bool {.ctoxProc.}
  var err: Tox_Err_File_Seek
    position: uint64; error: ptr Err_File_Seek): bool {.ctoxProc.}
  var err: Err_File_Seek
  discard tox.core.file_seek(friend, file, pos, addr err)
  ctoxAssert(TOX_ERR_FILE_SEEK_OK, err)

type Tox_Err_File_Get = enum
type Err_File_Get {.ctoxEnum.} = enum
  TOX_ERR_FILE_GET_OK,
  TOX_ERR_FILE_GET_NULL,
  TOX_ERR_FILE_GET_FRIEND_NOT_FOUND,


@@ 911,12 922,12 @@ proc id*(tox: Tox; friend: Friend; file: FileTransfer): FileId =
  proc file_get_file_id(
    core: Core; friend: Friend;
    file: FileTransfer; file_id: ptr uint8;
    error: ptr Tox_Err_File_Get): bool {.ctoxProc.}
  var err: Tox_Err_File_Get
    error: ptr Err_File_Get): bool {.ctoxProc.}
  var err: Err_File_Get
  discard tox.core.file_get_file_id(friend, file, addr result[0], addr err)
  ctoxAssert(TOX_ERR_FILE_GET_OK, err)

type Tox_Err_File_Send = enum
type Err_File_Send {.ctoxEnum.} = enum
  TOX_ERR_FILE_SEND_OK,
  TOX_ERR_FILE_SEND_NULL,
  TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND,


@@ 929,13 940,13 @@ proc send*(tox: Tox; friend: Friend; kind: uint32; size: BiggestInt; id: FileId;
  proc file_send(
    core: Core; friend: Friend; kind: uint32;
    file_size: uint64; file_id: ptr uint8; filename: cstring;
    filename_length: csize; error: ptr Tox_Err_File_Send): FileTransfer {.ctoxProc.}
  var err: Tox_Err_File_Send
    filename_length: csize; error: ptr Err_File_Send): FileTransfer {.ctoxProc.}
  var err: Err_File_Send
  result = tox.core.file_send(
    friend, kind, size.uint64, unsafeAddr id[0], filename, filename.len, addr err)
  ctoxAssert(TOX_ERR_FILE_SEND_OK, err)

type Tox_Err_File_Send_Chunk = enum
type Err_File_Send_Chunk {.ctoxEnum.} = enum
  TOX_ERR_FILE_SEND_CHUNK_OK,
  TOX_ERR_FILE_SEND_CHUNK_NULL,
  TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND,


@@ 952,8 963,8 @@ proc sendChunk*(tox: Tox; friend: Friend; file: FileTransfer; pos: uint64;
    core: Core; friend: Friend;
    file: FileTransfer; position: uint64;
    data: pointer; length: csize;
    error: ptr Tox_Err_File_Send_Chunk): bool {.ctoxProc.}
  var err: Tox_Err_File_Send_Chunk
    error: ptr Err_File_Send_Chunk): bool {.ctoxProc.}
  var err: Err_File_Send_Chunk
  discard tox.core.file_send_chunk(friend, file, pos, data, size, addr err)
  ctoxAssert(TOX_ERR_FILE_SEND_CHUNK_OK, err)



@@ 995,11 1006,11 @@ callbackSetter file_recv_chunk:
callbackSetter conference_invite:
  type cbType = proc (
    core: Core; friend: Friend;
    kind: TOX_CONFERENCE_TYPE; cookie: ptr uint8;
    kind: ConferenceType; cookie: ptr uint8;
    length: csize; user_data: pointer) {.cdecl.}
  proc wrapper(
      core: Core; friend: Friend;
      kind: TOX_CONFERENCE_TYPE; cookie: ptr uint8;
      kind: ConferenceType; cookie: ptr uint8;
      length: csize; user_data: pointer) {.cdecl.} =
    callThru(friend, kind, ctoxString(cookie, length))



@@ 1015,12 1026,12 @@ callbackSetter conference_connected:
callbackSetter conference_message:
  type cbType = proc (
    core: Core; conf: Conference;
    peer: Peer; kind: TOX_MESSAGE_TYPE;
    peer: Peer; kind: MessageType;
    message: ptr uint8; length: csize;
    user_data: pointer) {.cdecl.}
  proc wrapper(
      core: Core; conf: Conference;
      peer: Peer; kind: TOX_MESSAGE_TYPE;
      peer: Peer; kind: MessageType;
      message: ptr uint8; length: csize;
      user_data: pointer) {.cdecl.} =
    callThru(conf, peer, kind, ctoxString(message, length))


@@ 1054,31 1065,31 @@ callbackSetter conference_peer_list_changed:
      core: Core; conf: Conference; user_data: pointer) {.cdecl.} =
    callThru(conf)

type Tox_Err_Conference_New = enum
type Err_Conference_New {.ctoxEnum.} = enum
  TOX_ERR_CONFERENCE_NEW_OK,
  TOX_ERR_CONFERENCE_NEW_INIT

proc newConference*(tox: Tox): Conference {.tags: [IOEffect].} =
  proc conference_new(
    core: Core; error: ptr Tox_Err_Conference_New): Conference {.ctoxProc.}
  var err: Tox_Err_Conference_New
    core: Core; error: ptr Err_Conference_New): Conference {.ctoxProc.}
  var err: Err_Conference_New
  result = tox.core.conference_new(addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_NEW_OK, err)

type Tox_Err_Conference_Delete = enum
type Err_Conference_Delete {.ctoxEnum.} = enum
  TOX_ERR_CONFERENCE_DELETE_OK,
  TOX_ERR_CONFERENCE_DELETE_CONFERENCE_NOT_FOUND

proc delete*(tox: Tox; conf: Conference) {.tags: [IOEffect].} =
  proc tox_conference_delete(
    core: Core; conference: Conference;
    error: ptr Tox_Err_Conference_Delete): bool {.ctoxProc.}
  var err: Tox_Err_Conference_Delete
    error: ptr Err_Conference_Delete): bool {.ctoxProc.}
  var err: Err_Conference_Delete
  discard tox.core.tox_conference_delete(conf, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_DELETE_OK, err)

type
  Tox_Err_Conference_Peer_Query = enum
  Err_Conference_Peer_Query {.ctoxEnum.} = enum
    TOX_ERR_CONFERENCE_PEER_QUERY_OK,
    TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND,
    TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND,


@@ 1087,7 1098,7 @@ type
proc peerCount*(tox: Tox; conf: Conference): uint32 =
  proc conference_peer_count(
    core: Core; conf: Conference;
    error: ptr Tox_Err_Conference_Peer_Query): uint32 {.ctoxProc.}
    error: ptr Err_Conference_Peer_Query): uint32 {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_PEER_QUERY_OK
  result = tox.core.conference_peer_count(conf, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_PEER_QUERY_OK, err)


@@ 1095,10 1106,10 @@ proc peerCount*(tox: Tox; conf: Conference): uint32 =
proc peerName*(tox: Tox; conf: Conference; peer: Peer): string =
  proc conference_peer_get_name_size(
    core: Core; conf: Conference; peer: Peer;
    error: ptr Tox_Err_Conference_Peer_Query): csize {.ctoxProc.}
    error: ptr Err_Conference_Peer_Query): csize {.ctoxProc.}
  proc conference_peer_get_name(
    core: Core; conf: Conference; peer: Peer; name: ptr char;
    error: ptr Tox_Err_Conference_Peer_Query): bool {.ctoxProc.}
    error: ptr Err_Conference_Peer_Query): bool {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_PEER_QUERY_OK
  result = newString(tox.core.conference_peer_get_name_size(conf, peer, addr err))
  ctoxAssert(TOX_ERR_CONFERENCE_PEER_QUERY_OK, err)


@@ 1109,7 1120,7 @@ proc peerName*(tox: Tox; conf: Conference; peer: Peer): string =
proc peerPublicKey*(tox: Tox; conf: Conference; peer: Peer): PublicKey =
  proc conference_peer_get_public_key(
    core: Core; conf: Conference; peer: Peer; public_key: ptr uint8;
    error: ptr Tox_Err_Conference_Peer_Query): bool {.ctoxProc.}
    error: ptr Err_Conference_Peer_Query): bool {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_PEER_QUERY_OK
  discard tox.core.conference_peer_get_public_key(conf, peer, addr result.bytes[
      0], addr err)


@@ 1118,7 1129,7 @@ proc peerPublicKey*(tox: Tox; conf: Conference; peer: Peer): PublicKey =
proc peerNumberIsOurs*(tox: Tox; conf: Conference; peer: Peer): bool =
  proc conference_peer_number_is_ours(
    core: Core; conf: Conference; peer: Peer;
    error: ptr Tox_Err_Conference_Peer_Query): bool {.ctoxProc.}
    error: ptr Err_Conference_Peer_Query): bool {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_PEER_QUERY_OK
  result = tox.core.conference_peer_number_is_ours(conf, peer, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_PEER_QUERY_OK, err)


@@ 1126,7 1137,7 @@ proc peerNumberIsOurs*(tox: Tox; conf: Conference; peer: Peer): bool =
proc offlinePeerCount*(tox: Tox; conf: Conference): uint32 =
  proc conference_offline_peer_count(
    core: Core; conf: Conference;
    error: ptr Tox_Err_Conference_Peer_Query): uint32 {.ctoxProc.}
    error: ptr Err_Conference_Peer_Query): uint32 {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_PEER_QUERY_OK
  result = tox.core.conference_offline_peer_count(conf, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_PEER_QUERY_OK, err)


@@ 1134,10 1145,10 @@ proc offlinePeerCount*(tox: Tox; conf: Conference): uint32 =
proc offlinePeerName*(tox: Tox; conf: Conference; peer: Peer): string =
  proc conference_offline_peer_get_name_size(
    core: Core; conf: Conference; offline_peer: Peer;
    error: ptr Tox_Err_Conference_Peer_Query): csize {.ctoxProc.}
    error: ptr Err_Conference_Peer_Query): csize {.ctoxProc.}
  proc conference_offline_peer_get_name(core: Core;
      conf: Conference; offline_peer: Peer; name: ptr char;
      error: ptr Tox_Err_Conference_Peer_Query): bool {.ctoxProc.}
      error: ptr Err_Conference_Peer_Query): bool {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_PEER_QUERY_OK
  result = newString(tox.core.conference_offline_peer_get_name_size(conf, peer, addr err))
  ctoxAssert(TOX_ERR_CONFERENCE_PEER_QUERY_OK, err)


@@ 1149,7 1160,7 @@ proc offlinePeerName*(tox: Tox; conf: Conference; peer: Peer): string =
proc offlinePeerPublicKey*(tox: Tox; conf: Conference; peer: Peer): PublicKey =
  proc conference_offline_peer_get_public_key(
    core: Core; conf: Conference; offline_peer: Peer; public_key: ptr uint8;
    error: ptr Tox_Err_Conference_Peer_Query): bool {.ctoxProc.}
    error: ptr Err_Conference_Peer_Query): bool {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_PEER_QUERY_OK
  discard tox.core.conference_offline_peer_get_public_key(
    conf, peer, addr result.bytes[0], addr err)


@@ 1158,12 1169,12 @@ proc offlinePeerPublicKey*(tox: Tox; conf: Conference; peer: Peer): PublicKey =
proc offflinePeerLastActive*(tox: Tox; conf: Conference; peer: Peer): uint64 =
  proc conference_offline_peer_get_last_active(
    core: Core; conf: Conference; offline_peer: Peer;
    error: ptr Tox_Err_Conference_Peer_Query): uint64 {.ctoxProc.}
    error: ptr Err_Conference_Peer_Query): uint64 {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_PEER_QUERY_OK
  result = tox.core.conference_offline_peer_get_last_active(conf, peer, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_PEER_QUERY_OK, err)

type Tox_Err_Conference_Set_Max_Offline = enum
type Err_Conference_Set_Max_Offline {.ctoxEnum.} = enum
  TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_OK,
  TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_CONFERENCE_NOT_FOUND



@@ 1171,12 1182,12 @@ proc `maxOffline=`*(tox: Tox; conf: Conference; peers: uint32) =
  proc conference_set_max_offline(
    core: Core; conf: Conference;
    max_offline_peers: uint32;
    error: ptr Tox_Err_Conference_Set_Max_Offline): bool {.ctoxProc.}
    error: ptr Err_Conference_Set_Max_Offline): bool {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_OK
  discard tox.core.conference_set_max_offline(conf, peers, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_OK, err)

type Tox_Err_Conference_Invite = enum
type Err_Conference_Invite {.ctoxEnum.} = enum
  TOX_ERR_CONFERENCE_INVITE_OK,
  TOX_ERR_CONFERENCE_INVITE_CONFERENCE_NOT_FOUND,
  TOX_ERR_CONFERENCE_INVITE_FAIL_SEND,


@@ 1186,12 1197,12 @@ proc invite*(tox: Tox; friend: Friend; conf: Conference) {.tags: [IOEffect].} =
  proc conference_invite(
    core: Core; friend: Friend;
    conference: Conference;
    error: ptr Tox_Err_Conference_Invite): bool {.ctoxProc.}
    error: ptr Err_Conference_Invite): bool {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_INVITE_OK
  discard tox.core.conference_invite(friend, conf, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_INVITE_OK, err)

type Tox_Err_Conference_Join = enum
type Err_Conference_Join {.ctoxEnum.} = enum
  TOX_ERR_CONFERENCE_JOIN_OK,
  TOX_ERR_CONFERENCE_JOIN_INVALID_LENGTH,
  TOX_ERR_CONFERENCE_JOIN_WRONG_TYPE,


@@ 1203,31 1214,31 @@ type Tox_Err_Conference_Join = enum
proc join*(tox: Tox; friend: Friend; cookie: string): Conference {.tags: [IOEffect].} =
  proc conference_join(
    core: Core; friend: Friend; cookie: cstring;
    length: csize; error: ptr Tox_Err_Conference_Join): Conference {.ctoxProc.}
    length: csize; error: ptr Err_Conference_Join): Conference {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_JOIN_OK
  result = tox.core.conference_join(friend, cookie, cookie.len, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_JOIN_OK, err)

type Tox_Err_Conference_Send_Message = enum
type Err_Conference_Send_Message {.ctoxEnum.} = enum
  TOX_ERR_CONFERENCE_SEND_MESSAGE_OK,
  TOX_ERR_CONFERENCE_SEND_MESSAGE_CONFERENCE_NOT_FOUND,
  TOX_ERR_CONFERENCE_SEND_MESSAGE_TOO_LONG,
  TOX_ERR_CONFERENCE_SEND_MESSAGE_NO_CONNECTION,
  TOX_ERR_CONFERENCE_SEND_MESSAGE_FAIL_SEND

proc send*(tox: Tox; conf: Conference; kind: TOX_MESSAGE_TYPE; msg: string) {.
proc send*(tox: Tox; conf: Conference; kind: MessageType; msg: string) {.
    tags: [IOEffect].} =
  proc conference_send_message(
    core: Core; conf: Conference;
    kind: TOX_MESSAGE_TYPE; message: cstring;
    kind: MessageType; message: cstring;
    length: csize;
    error: ptr Tox_Err_Conference_Send_Message): bool {.ctoxProc.}
    error: ptr Err_Conference_Send_Message): bool {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_SEND_MESSAGE_OK
  discard tox.core.conference_send_message(
    conf, kind, msg, msg.len, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_SEND_MESSAGE_OK, err)

type Tox_Err_Conference_Title = enum
type Err_Conference_Title {.ctoxEnum.} = enum
  TOX_ERR_CONFERENCE_TITLE_OK,
  TOX_ERR_CONFERENCE_TITLE_CONFERENCE_NOT_FOUND,
  TOX_ERR_CONFERENCE_TITLE_INVALID_LENGTH,


@@ 1236,10 1247,10 @@ type Tox_Err_Conference_Title = enum
proc title*(tox: Tox; conf: Conference): string =
  proc conference_get_title_size(
    core: Core; conf: Conference;
    error: ptr Tox_Err_Conference_Title): csize {.ctoxProc.}
    error: ptr Err_Conference_Title): csize {.ctoxProc.}
  proc conference_get_title(
    core: Core; conf: Conference; title: ptr char;
    error: ptr Tox_Err_Conference_Title): bool {.ctoxProc.}
    error: ptr Err_Conference_Title): bool {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_TITLE_OK
  result = newString(tox.core.conference_get_title_size(conf, addr err))
  ctoxAssert(TOX_ERR_CONFERENCE_TITLE_OK, err)


@@ 1251,7 1262,7 @@ proc `title=`*(tox: Tox; conf: Conference; s: string) {.tags: [IOEffect].} =
  proc conference_set_title(
    core: Core; conf: Conference;
    title: cstring; length: csize;
    error: ptr Tox_Err_Conference_Title): bool {.ctoxProc.}
    error: ptr Err_Conference_Title): bool {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_TITLE_OK
  discard tox.core.conference_set_title(conf, s, s.len, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_TITLE_OK, err)


@@ 1263,14 1274,14 @@ proc conferences*(tox: Tox): seq[Conference] =
  if 0 < result.len:
    tox.core.conference_get_chatlist(addr result[0])

type Tox_Err_Conference_Get_Type = enum
type Err_Conference_Get_Type {.ctoxEnum.} = enum
  TOX_ERR_CONFERENCE_GET_TYPE_OK,
  TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND

proc kind*(tox: Tox; conf: Conference): TOX_CONFERENCE_TYPE =
proc kind*(tox: Tox; conf: Conference): ConferenceType =
  proc conference_get_type(
    core: Core; conf: Conference;
    error: ptr Tox_Err_Conference_Get_Type): TOX_CONFERENCE_TYPE {.ctoxProc.}
    error: ptr Err_Conference_Get_Type): ConferenceType {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_GET_TYPE_OK
  result = tox.core.conference_get_type(conf, addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_GET_TYPE_OK, err)


@@ 1279,7 1290,7 @@ proc id*(tox: Tox; conf: Conference): ConferenceId =
  proc conference_get_id(core: Core; conf: Conference; id: ptr uint8): bool {.ctoxProc.}
  ctoxAssert(true, tox.core.conference_get_id(conf, addr result.bytes[0]))

type Tox_Err_Conference_By_Id = enum
type Err_Conference_By_Id {.ctoxEnum.} = enum
  TOX_ERR_CONFERENCE_BY_ID_OK,
  TOX_ERR_CONFERENCE_BY_ID_NULL,
  TOX_ERR_CONFERENCE_BY_ID_NOT_FOUND


@@ 1287,7 1298,7 @@ type Tox_Err_Conference_By_Id = enum
proc conference*(tox: Tox; id: ConferenceId): Conference =
  proc conference_by_id(
    core: Core; id: ptr uint8;
    error: ptr TOX_ERR_CONFERENCE_BY_ID): Conference {.ctoxProc.}
    error: ptr ERR_CONFERENCE_BY_ID): Conference {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_BY_ID_OK
  result = tox.core.conference_by_id(unsafeAddr id.bytes[0], addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_BY_ID_OK, err)


@@ 1297,7 1308,7 @@ proc uid*(tox: Tox; conf: Conference): ConferenceUid =
    core: Core; conf: Conference; uid: ptr uint8): bool {.ctoxProc.}
  ctoxAssert(true, tox.core.conference_get_uid(conf, addr result.bytes[0]))

type Tox_Err_Conference_By_Uid = enum
type Err_Conference_By_Uid {.ctoxEnum.} = enum
  TOX_ERR_CONFERENCE_BY_UID_OK,
  TOX_ERR_CONFERENCE_BY_UID_NULL,
  TOX_ERR_CONFERENCE_BY_UID_NOT_FOUND


@@ 1305,12 1316,12 @@ type Tox_Err_Conference_By_Uid = enum
proc conference*(tox: Tox; uid: ConferenceUid): Conference =
  proc conference_by_uid(
    core: Core; uid: ptr uint8;
    error: ptr Tox_Err_Conference_By_Uid): Conference {.ctoxProc.}
    error: ptr Err_Conference_By_Uid): Conference {.ctoxProc.}
  var err = TOX_ERR_CONFERENCE_BY_UID_OK
  result = tox.core.conference_by_uid(unsafeAddr uid.bytes[0], addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_BY_UID_OK, err)

type Tox_Err_Friend_Custom_Packet = enum
type Err_Friend_Custom_Packet {.ctoxEnum.} = enum
  TOX_ERR_FRIEND_CUSTOM_PACKET_OK,
  TOX_ERR_FRIEND_CUSTOM_PACKET_NULL,
  TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND,


@@ 1325,7 1336,7 @@ proc sendLossyPacket*(tox: Tox; friend: Friend; data: pointer; size: int) {.
  proc friend_send_lossy_packet(
    core: Core; friend: Friend;
    data: pointer; length: csize;
    error: ptr Tox_Err_Friend_Custom_Packet): bool {.ctoxProc.}
    error: ptr Err_Friend_Custom_Packet): bool {.ctoxProc.}
  var err = TOX_ERR_FRIEND_CUSTOM_PACKET_OK
  discard tox.core.friend_send_lossy_packet(friend, data, size, addr err)
  ctoxAssert(TOX_ERR_FRIEND_CUSTOM_PACKET_OK, err)


@@ 1335,7 1346,7 @@ proc sendLosslessPacket*(tox: Tox; friend: Friend; data: pointer; size: int) {.
  proc friend_send_lossless_packet(
    core: Core; friend: Friend;
    data: pointer; length: csize;
    error: ptr Tox_Err_Friend_Custom_Packet): bool {.ctoxProc.}
    error: ptr Err_Friend_Custom_Packet): bool {.ctoxProc.}
  var err = TOX_ERR_FRIEND_CUSTOM_PACKET_OK
  discard tox.core.friend_send_lossless_packet(friend, data, size, addr err)
  ctoxAssert(TOX_ERR_FRIEND_CUSTOM_PACKET_OK, err)


@@ 1366,20 1377,20 @@ proc dhtId*(tox: Tox): PublicKey =
  proc self_get_dht_id(core: Core; dht_id: ptr uint8) {.ctoxProc.}
  tox.core.self_get_dht_id(addr result.bytes[0])

type Tox_Err_Get_Port = enum
type Err_Get_Port {.ctoxEnum.} = enum
  TOX_ERR_GET_PORT_OK,
  TOX_ERR_GET_PORT_NOT_BOUND

proc udpPort*(tox: Tox): uint16 =
  proc self_get_udp_port(
    core: Core; error: ptr Tox_Err_Get_Port): uint16 {.ctoxProc.}
    core: Core; error: ptr Err_Get_Port): uint16 {.ctoxProc.}
  var err = TOX_ERR_GET_PORT_OK
  result = tox.core.self_get_udp_port(addr err)
  ctoxAssert(TOX_ERR_GET_PORT_OK, err)

proc tcpPort*(tox: Tox): uint16 =
  proc self_get_tcp_port(
    core: Core; error: ptr Tox_Err_Get_Port): uint16 {.ctoxProc.}
    core: Core; error: ptr Err_Get_Port): uint16 {.ctoxProc.}
  var err = TOX_ERR_GET_PORT_OK
  result = tox.core.self_get_tcp_port(addr err)
  ctoxAssert(TOX_ERR_GET_PORT_OK, err)

M tests/node.nim => tests/node.nim +5 -5
@@ 10,11 10,11 @@ onSignal(SIGINT, SIGTERM):
  quit(0)

proc logCb(
    core: Core; level: TOX_LOG_LEVEL; file: cstring; line: uint32;
    core: Core; level: LogLevel; file: cstring; line: uint32;
    `func`: cstring; message: cstring; user_data: pointer) {.cdecl.} =
  echo level, " ", file, ":", line, " ", `func`, " ", message

proc connectionStatus(status: TOX_CONNECTION) =
proc connectionStatus(status: Connection) =
  echo "connection status update: ", status

proc friendName*(friend: Friend; name: string) =


@@ 23,10 23,10 @@ proc friendName*(friend: Friend; name: string) =
proc friendStatusMessage(friend: Friend; msg: string) =
  echo "friend ", friend.int, " status is now ", msg

proc friendStatus(friend: Friend; status: TOX_USER_STATUS) =
proc friendStatus(friend: Friend; status: UserStatus) =
  echo "friend ", friend.int, " status is now ", status

proc friendConnectionStatus(friend: Friend; status: TOX_CONNECTION) =
proc friendConnectionStatus(friend: Friend; status: Connection) =
  echo "friend ", friend.int, " status is now ", status

proc friendTyping(friend: Friend; typing: bool) =


@@ 39,7 39,7 @@ proc friendReadReceipt(friend: Friend; id: MessageId) =
  echo "friend ", friend.int, " has read message ", id.int


proc friendMessage(friend: Friend; msg: string; kind: TOX_MESSAGE_TYPE) =
proc friendMessage(friend: Friend; msg: string; kind: MessageType) =
  echo "friend sends ", kind, " message: ", msg

proc createTox(): Tox =

M tests/simple.nim => tests/simple.nim +1 -1
@@ 13,7 13,7 @@ proc setupCallbacks(bot: Tox) =
  bot.onFriendRequest do (pk: PublicKey; msg: string):
    discard bot.addFriendNoRequest(pk)

  bot.onFriendMessage do (f: Friend; msg: string; kind: TOX_MESSAGE_TYPE):
  bot.onFriendMessage do (f: Friend; msg: string; kind: MessageType):
    discard bot.send(f, msg, kind)
    inc echoCount
    bot.statusMessage = $echoCount & " echos served "

M tests/test1.nim => tests/test1.nim +4 -1
@@ 2,7 2,10 @@ import unittest

import toxcore

test "basic":
test "version":
  check versionIsCompatible()

test "newTox":
  let tox = newTox()
  check(tox.address.isValid)
  close tox

M toxcore.nimble => toxcore.nimble +1 -1
@@ 1,6 1,6 @@
# Package

version       = "0.1.1"
version       = "0.2.0"
author        = "Emery Hemingway"
description   = "C Tox core wrapper"
license       = "GPL-3.0-or-later"