~ehmry/nim_tox

6dbef60d47f986a152c14c85bc0990fa840c1ea3 — Emery Hemingway 2 months ago 468dddf
Nim 1.0.2 compability, nimpretty
5 files changed, 153 insertions(+), 137 deletions(-)

M README.md
A shell.nix
M src/toxcore.nim
M tests/simple.nim
M toxcore.nimble
M README.md => README.md +1 -1
@@ 17,7 17,7 @@ proc setupCallbacks(bot: Tox) =
    discard bot.addFriendNoRequest(pk)

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


A shell.nix => shell.nix +2 -0
@@ 0,0 1,2 @@
{ pkgs ? import <nixpkgs> { } }:
pkgs.mkShell { buildInputs = with pkgs; [ nim libtoxcore pkgconfig ]; }

M src/toxcore.nim => src/toxcore.nim +147 -133
@@ 131,7 131,7 @@ func isValid*(id: Address): bool =
template toxIndexType(T: untyped) =
  ## Generate a index type definition with equality comparison.
  type T* = distinct uint32
  proc `==` * (x, y: T): bool {.borrow.}
  proc `==`*(x, y: T): bool {.borrow.}

toxIndexType Friend
toxIndexType NoSpam


@@ 228,9 228,11 @@ type
  CbFileChunkRequest* = proc (
    friend: Friend; file: FileTransfer; pos: uint64; size: int) {.gcsafe.}
  CbFileRecv* = proc (
    friend: Friend; file: FileTransfer; kind: uint32; size: uint64; filename: string) {.gcsafe.}
    friend: Friend; file: FileTransfer; kind: uint32; size: uint64;
        filename: string) {.gcsafe.}
  CbFileRecvChunk* = proc (
    friend: Friend; file: FileTransfer; pos: uint64; data: pointer; size: int) {.gcsafe.}
    friend: Friend; file: FileTransfer; pos: uint64; data: pointer;
        size: int) {.gcsafe.}

  CbConferenceInvite* = proc (
    friend: Friend; kind: TOX_CONFERENCE_TYPE; cookie: string) {.gcsafe.}


@@ 290,7 292,8 @@ proc `udp_enabled=`*(options: Options; udp_enabled: bool) {.
  importc: "tox_options_set_udp_enabled".}

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

proc proxy_type*(options: Options): TOX_PROXY_TYPE {.ctox_options_get.}


@@ 320,7 323,7 @@ proc `tcp_port=`*(options: Options; tcp_port: uint16) {.
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".}
    

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".}


@@ 329,7 332,8 @@ 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_data(options: Options; data: cstring;
      length: csize) {.ctoxProc.}
  # proc options_set_savedata_length(options: Options; length: csize) {.ctoxProc.}
  options.options_set_savedata_data(data, data.len)



@@ 423,7 427,8 @@ type
const
  defaultPort* = 33445'u16

proc bootstrap*(tox: Tox; host: string; key: PublicKey; port = defaultPort) {.tags: [IOEffect].} =
proc bootstrap*(tox: Tox; host: string; key: PublicKey; port = defaultPort) {.
    tags: [IOEffect].} =
  ## Bootstap the `tox` DHT state.
  proc bootstrap(
    core: Core; host: cstring; port: uint16;


@@ 443,10 448,10 @@ proc addTcpRelay*(tox: Tox; host: string; port: uint16; key: PublicKey) =

template callbackSetter(name, body: untyped) =
  ## Magic for installing Nim closure callbacks into c-toxcore.
  template callThru(args: varargs[untyped]) =
    let tox = cast[Tox](user_data)
    if not tox.name.isNil: tox.name(args)
  proc `on name`*(tox: Tox; cb: `Cb name`) =
    template callThru(args: varargs[untyped]) =
      let tox = cast[Tox](user_data)
      if not tox.name.isNil: tox.name(args)
    body
    proc name(core: Core; callback: cbType) {.ctoxCallbackProc.}
    tox.name = cb


@@ 483,10 488,10 @@ proc address*(tox: Tox): Address =
  proc self_get_address(core: Core; address: ptr uint8) {.ctoxProc.}
  tox.core.self_get_address(addr result.bytes[0])

proc `noSpam=`*(tox: Tox, noSpam: NoSpam) =
proc `noSpam=`*(tox: Tox; noSpam: NoSpam) =
  ## Set a new nospam cookie. This prevents new friend requests
  ## using the previous nospam from reaching `tox`.
  proc self_set_nospam(core: Core, nospam: NoSpam) {.ctoxProc.}
  proc self_set_nospam(core: Core; nospam: NoSpam) {.ctoxProc.}
  tox.core.self_set_nospam(noSpam)

proc noSpam*(tox: Tox): NoSpam =


@@ 555,17 560,17 @@ proc status*(tox: Tox): TOX_USER_STATUS =
  tox.core.self_get_status()

type Tox_Err_Friend_Add = enum
    TOX_ERR_FRIEND_ADD_OK,
    TOX_ERR_FRIEND_ADD_NULL,
    TOX_ERR_FRIEND_ADD_TOO_LONG,
    TOX_ERR_FRIEND_ADD_NO_MESSAGE,
    TOX_ERR_FRIEND_ADD_OWN_KEY,
    TOX_ERR_FRIEND_ADD_ALREADY_SENT,
    TOX_ERR_FRIEND_ADD_BAD_CHECKSUM,
    TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM,
    TOX_ERR_FRIEND_ADD_MALLOC

proc addFriend*(tox: Tox; id: Address, msg: string): Friend {.tags: [IOEffect].} =
  TOX_ERR_FRIEND_ADD_OK,
  TOX_ERR_FRIEND_ADD_NULL,
  TOX_ERR_FRIEND_ADD_TOO_LONG,
  TOX_ERR_FRIEND_ADD_NO_MESSAGE,
  TOX_ERR_FRIEND_ADD_OWN_KEY,
  TOX_ERR_FRIEND_ADD_ALREADY_SENT,
  TOX_ERR_FRIEND_ADD_BAD_CHECKSUM,
  TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM,
  TOX_ERR_FRIEND_ADD_MALLOC

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;


@@ 599,9 604,9 @@ proc delete*(tox: Tox; friend: Friend): bool {.tags: [IOEffect].} =
  ctoxAssert(TOX_ERR_FRIEND_DELETE_OK, err)

type Tox_Err_Friend_By_Public_Key = enum
    TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK,
    TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL,
    TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND
  TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK,
  TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL,
  TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND

proc friend*(tox: Tox; key: PublicKey): Friend =
  ## Retrieve a friend handle by public key.


@@ 626,8 631,8 @@ proc friends*(tox: Tox): seq[Friend] =
    tox.core.self_get_friend_list(addr result[0])

type Tox_Err_Friend_Get_Public_Key = enum
    TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK,
    TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND
  TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK,
  TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND

proc publicKey*(tox: Tox; friend: Friend): PublicKey =
  ## Retrieve the public key for a given friend handle.


@@ 640,8 645,8 @@ proc publicKey*(tox: Tox; friend: Friend): PublicKey =
  ctoxAssert(TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK, err)

type Tox_Err_Friend_Get_Last_Online = enum
    TOX_ERR_FRIEND_GET_LAST_ONLINE_OK,
    TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND
  TOX_ERR_FRIEND_GET_LAST_ONLINE_OK,
  TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND

proc lastOnline*(tox: Tox; friend: Friend): uint64 =
  ## Retrieve the last time a friend was known to be online in Unix epoch time.


@@ 653,9 658,9 @@ proc lastOnline*(tox: Tox; friend: Friend): uint64 =
  ctoxAssert(TOX_ERR_FRIEND_GET_LAST_ONLINE_OK, err)

type Tox_Err_Friend_Query = enum
    TOX_ERR_FRIEND_QUERY_OK,
    TOX_ERR_FRIEND_QUERY_NULL,
    TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND
  TOX_ERR_FRIEND_QUERY_OK,
  TOX_ERR_FRIEND_QUERY_NULL,
  TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND

proc name*(tox: Tox; friend: Friend): string =
  ## Retrieve the name of a friend by handle.


@@ 786,15 791,16 @@ proc typing*(tox: Tox; friend: Friend; typing: bool) {.tags: [IOEffect].} =
  ctoxAssert(TOX_ERR_SET_TYPING_OK, err)

type Tox_Err_Friend_Send_Message = enum
    TOX_ERR_FRIEND_SEND_MESSAGE_OK,
    TOX_ERR_FRIEND_SEND_MESSAGE_NULL,
    TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND,
    TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED,
    TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ,
    TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG,
    TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY

proc send*(tox: Tox; friend: Friend; msg: string; kind = TOX_MESSAGE_TYPE_NORMAL): MessageId {.tags: [IOEffect].} =
  TOX_ERR_FRIEND_SEND_MESSAGE_OK,
  TOX_ERR_FRIEND_SEND_MESSAGE_NULL,
  TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND,
  TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED,
  TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ,
  TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG,
  TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY

proc send*(tox: Tox; friend: Friend; msg: string;
    kind = TOX_MESSAGE_TYPE_NORMAL): MessageId {.tags: [IOEffect].} =
  ## Send a message to a friend.
  proc friend_send_message(
    core: Core; friend: Friend;


@@ 846,16 852,17 @@ proc hash*(data: pointer; size: int): Hash =
  discard hash(addr result.bytes[0], data, size)

type Tox_Err_File_Control = enum
    TOX_ERR_FILE_CONTROL_OK,
    TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND,
    TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED,
    TOX_ERR_FILE_CONTROL_NOT_FOUND,
    TOX_ERR_FILE_CONTROL_NOT_PAUSED,
    TOX_ERR_FILE_CONTROL_DENIED,
    TOX_ERR_FILE_CONTROL_ALREADY_PAUSED,
    TOX_ERR_FILE_CONTROL_SENDQ

proc control*(tox: Tox; friend: Friend; file: FileTransfer; control: TOX_FILE_CONTROL) {.tags: [IOEffect].} =
  TOX_ERR_FILE_CONTROL_OK,
  TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND,
  TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED,
  TOX_ERR_FILE_CONTROL_NOT_FOUND,
  TOX_ERR_FILE_CONTROL_NOT_PAUSED,
  TOX_ERR_FILE_CONTROL_DENIED,
  TOX_ERR_FILE_CONTROL_ALREADY_PAUSED,
  TOX_ERR_FILE_CONTROL_SENDQ

proc control*(tox: Tox; friend: Friend; file: FileTransfer;
    control: TOX_FILE_CONTROL) {.tags: [IOEffect].} =
  proc file_control(
    core: Core; friend: Friend; file: FileTransfer;
    control: TOX_FILE_CONTROL;


@@ 876,13 883,13 @@ callbackSetter file_recv_control:
    callThru(friend, file, control)

type Tox_Err_File_Seek = enum
    TOX_ERR_FILE_SEEK_OK,
    TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND,
    TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED,
    TOX_ERR_FILE_SEEK_NOT_FOUND,
    TOX_ERR_FILE_SEEK_DENIED,
    TOX_ERR_FILE_SEEK_INVALID_POSITION,
    TOX_ERR_FILE_SEEK_SENDQ
  TOX_ERR_FILE_SEEK_OK,
  TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND,
  TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED,
  TOX_ERR_FILE_SEEK_NOT_FOUND,
  TOX_ERR_FILE_SEEK_DENIED,
  TOX_ERR_FILE_SEEK_INVALID_POSITION,
  TOX_ERR_FILE_SEEK_SENDQ

proc seek*(tox: Tox; friend: Friend; file: FileTransfer; pos: uint64) {.tags: [IOEffect].} =
  proc file_seek(


@@ 893,10 900,10 @@ proc seek*(tox: Tox; friend: Friend; file: FileTransfer; pos: uint64) {.tags: [I
  ctoxAssert(TOX_ERR_FILE_SEEK_OK, err)

type Tox_Err_File_Get = enum
    TOX_ERR_FILE_GET_OK,
    TOX_ERR_FILE_GET_NULL,
    TOX_ERR_FILE_GET_FRIEND_NOT_FOUND,
    TOX_ERR_FILE_GET_NOT_FOUND
  TOX_ERR_FILE_GET_OK,
  TOX_ERR_FILE_GET_NULL,
  TOX_ERR_FILE_GET_FRIEND_NOT_FOUND,
  TOX_ERR_FILE_GET_NOT_FOUND

type FileId = array[TOX_FILE_ID_LENGTH, uint8]



@@ 910,14 917,15 @@ proc id*(tox: Tox; friend: Friend; file: FileTransfer): FileId =
  ctoxAssert(TOX_ERR_FILE_GET_OK, err)

type Tox_Err_File_Send = enum
    TOX_ERR_FILE_SEND_OK,
    TOX_ERR_FILE_SEND_NULL,
    TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND,
    TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED,
    TOX_ERR_FILE_SEND_NAME_TOO_LONG,
    TOX_ERR_FILE_SEND_TOO_MANY

proc send*(tox: Tox; friend: Friend; kind: uint32; size: BiggestInt; id: FileId; filename: string): FileTransfer {.tags: [IOEffect].} =
  TOX_ERR_FILE_SEND_OK,
  TOX_ERR_FILE_SEND_NULL,
  TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND,
  TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED,
  TOX_ERR_FILE_SEND_NAME_TOO_LONG,
  TOX_ERR_FILE_SEND_TOO_MANY

proc send*(tox: Tox; friend: Friend; kind: uint32; size: BiggestInt; id: FileId;
    filename: string): FileTransfer {.tags: [IOEffect].} =
  proc file_send(
    core: Core; friend: Friend; kind: uint32;
    file_size: uint64; file_id: ptr uint8; filename: cstring;


@@ 928,17 936,18 @@ proc send*(tox: Tox; friend: Friend; kind: uint32; size: BiggestInt; id: FileId;
  ctoxAssert(TOX_ERR_FILE_SEND_OK, err)

type Tox_Err_File_Send_Chunk = enum
    TOX_ERR_FILE_SEND_CHUNK_OK,
    TOX_ERR_FILE_SEND_CHUNK_NULL,
    TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND,
    TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED,
    TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND,
    TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING,
    TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH,
    TOX_ERR_FILE_SEND_CHUNK_SENDQ,
    TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION

proc sendChunk*(tox: Tox; friend: Friend; file: FileTransfer; pos: uint64; data: pointer; size: int) {.tags: [IOEffect].} =
  TOX_ERR_FILE_SEND_CHUNK_OK,
  TOX_ERR_FILE_SEND_CHUNK_NULL,
  TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND,
  TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED,
  TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND,
  TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING,
  TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH,
  TOX_ERR_FILE_SEND_CHUNK_SENDQ,
  TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION

proc sendChunk*(tox: Tox; friend: Friend; file: FileTransfer; pos: uint64;
    data: pointer; size: int) {.tags: [IOEffect].} =
  proc file_send_chunk(
    core: Core; friend: Friend;
    file: FileTransfer; position: uint64;


@@ 1046,8 1055,8 @@ callbackSetter conference_peer_list_changed:
    callThru(conf)

type Tox_Err_Conference_New = enum
    TOX_ERR_CONFERENCE_NEW_OK,
    TOX_ERR_CONFERENCE_NEW_INIT
  TOX_ERR_CONFERENCE_NEW_OK,
  TOX_ERR_CONFERENCE_NEW_INIT

proc newConference*(tox: Tox): Conference {.tags: [IOEffect].} =
  proc conference_new(


@@ 1057,8 1066,8 @@ proc newConference*(tox: Tox): Conference {.tags: [IOEffect].} =
  ctoxAssert(TOX_ERR_CONFERENCE_NEW_OK, err)

type Tox_Err_Conference_Delete = enum
    TOX_ERR_CONFERENCE_DELETE_OK,
    TOX_ERR_CONFERENCE_DELETE_CONFERENCE_NOT_FOUND
  TOX_ERR_CONFERENCE_DELETE_OK,
  TOX_ERR_CONFERENCE_DELETE_CONFERENCE_NOT_FOUND

proc delete*(tox: Tox; conf: Conference) {.tags: [IOEffect].} =
  proc tox_conference_delete(


@@ 1102,7 1111,8 @@ proc peerPublicKey*(tox: Tox; conf: Conference; peer: Peer): PublicKey =
    core: Core; conf: Conference; peer: Peer; public_key: ptr uint8;
    error: ptr Tox_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)
  discard tox.core.conference_peer_get_public_key(conf, peer, addr result.bytes[
      0], addr err)
  ctoxAssert(TOX_ERR_CONFERENCE_PEER_QUERY_OK, err)

proc peerNumberIsOurs*(tox: Tox; conf: Conference; peer: Peer): bool =


@@ 1132,7 1142,8 @@ proc offlinePeerName*(tox: Tox; conf: Conference; peer: Peer): string =
  result = newString(tox.core.conference_offline_peer_get_name_size(conf, peer, addr err))
  ctoxAssert(TOX_ERR_CONFERENCE_PEER_QUERY_OK, err)
  if 0 < result.len:
    discard tox.core.conference_offline_peer_get_name(conf, peer, addr result[0], addr err)
    discard tox.core.conference_offline_peer_get_name(conf, peer, addr result[
        0], addr err)
    ctoxAssert(TOX_ERR_CONFERENCE_PEER_QUERY_OK, err)

proc offlinePeerPublicKey*(tox: Tox; conf: Conference; peer: Peer): PublicKey =


@@ 1153,8 1164,8 @@ proc offflinePeerLastActive*(tox: Tox; conf: Conference; peer: Peer): uint64 =
  ctoxAssert(TOX_ERR_CONFERENCE_PEER_QUERY_OK, err)

type Tox_Err_Conference_Set_Max_Offline = enum
    TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_OK,
    TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_CONFERENCE_NOT_FOUND
  TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_OK,
  TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_CONFERENCE_NOT_FOUND

proc `maxOffline=`*(tox: Tox; conf: Conference; peers: uint32) =
  proc conference_set_max_offline(


@@ 1166,10 1177,10 @@ proc `maxOffline=`*(tox: Tox; conf: Conference; peers: uint32) =
  ctoxAssert(TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_OK, err)

type Tox_Err_Conference_Invite = enum
    TOX_ERR_CONFERENCE_INVITE_OK,
    TOX_ERR_CONFERENCE_INVITE_CONFERENCE_NOT_FOUND,
    TOX_ERR_CONFERENCE_INVITE_FAIL_SEND,
    TOX_ERR_CONFERENCE_INVITE_NO_CONNECTION
  TOX_ERR_CONFERENCE_INVITE_OK,
  TOX_ERR_CONFERENCE_INVITE_CONFERENCE_NOT_FOUND,
  TOX_ERR_CONFERENCE_INVITE_FAIL_SEND,
  TOX_ERR_CONFERENCE_INVITE_NO_CONNECTION

proc invite*(tox: Tox; friend: Friend; conf: Conference) {.tags: [IOEffect].} =
  proc conference_invite(


@@ 1181,13 1192,13 @@ proc invite*(tox: Tox; friend: Friend; conf: Conference) {.tags: [IOEffect].} =
  ctoxAssert(TOX_ERR_CONFERENCE_INVITE_OK, err)

type Tox_Err_Conference_Join = enum
    TOX_ERR_CONFERENCE_JOIN_OK,
    TOX_ERR_CONFERENCE_JOIN_INVALID_LENGTH,
    TOX_ERR_CONFERENCE_JOIN_WRONG_TYPE,
    TOX_ERR_CONFERENCE_JOIN_FRIEND_NOT_FOUND,
    TOX_ERR_CONFERENCE_JOIN_DUPLICATE,
    TOX_ERR_CONFERENCE_JOIN_INIT_FAIL,
    TOX_ERR_CONFERENCE_JOIN_FAIL_SEND
  TOX_ERR_CONFERENCE_JOIN_OK,
  TOX_ERR_CONFERENCE_JOIN_INVALID_LENGTH,
  TOX_ERR_CONFERENCE_JOIN_WRONG_TYPE,
  TOX_ERR_CONFERENCE_JOIN_FRIEND_NOT_FOUND,
  TOX_ERR_CONFERENCE_JOIN_DUPLICATE,
  TOX_ERR_CONFERENCE_JOIN_INIT_FAIL,
  TOX_ERR_CONFERENCE_JOIN_FAIL_SEND

proc join*(tox: Tox; friend: Friend; cookie: string): Conference {.tags: [IOEffect].} =
  proc conference_join(


@@ 1198,13 1209,14 @@ proc join*(tox: Tox; friend: Friend; cookie: string): Conference {.tags: [IOEffe
  ctoxAssert(TOX_ERR_CONFERENCE_JOIN_OK, err)

type Tox_Err_Conference_Send_Message = 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) {.tags: [IOEffect].} =
  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) {.
    tags: [IOEffect].} =
  proc conference_send_message(
    core: Core; conf: Conference;
    kind: TOX_MESSAGE_TYPE; message: cstring;


@@ 1216,10 1228,10 @@ proc send*(tox: Tox; conf: Conference; kind: TOX_MESSAGE_TYPE; msg: string) {.ta
  ctoxAssert(TOX_ERR_CONFERENCE_SEND_MESSAGE_OK, err)

type Tox_Err_Conference_Title = enum
    TOX_ERR_CONFERENCE_TITLE_OK,
    TOX_ERR_CONFERENCE_TITLE_CONFERENCE_NOT_FOUND,
    TOX_ERR_CONFERENCE_TITLE_INVALID_LENGTH,
    TOX_ERR_CONFERENCE_TITLE_FAIL_SEND
  TOX_ERR_CONFERENCE_TITLE_OK,
  TOX_ERR_CONFERENCE_TITLE_CONFERENCE_NOT_FOUND,
  TOX_ERR_CONFERENCE_TITLE_INVALID_LENGTH,
  TOX_ERR_CONFERENCE_TITLE_FAIL_SEND

proc title*(tox: Tox; conf: Conference): string =
  proc conference_get_title_size(


@@ 1252,8 1264,8 @@ proc conferences*(tox: Tox): seq[Conference] =
    tox.core.conference_get_chatlist(addr result[0])

type Tox_Err_Conference_Get_Type = enum
    TOX_ERR_CONFERENCE_GET_TYPE_OK,
    TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND
  TOX_ERR_CONFERENCE_GET_TYPE_OK,
  TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND

proc kind*(tox: Tox; conf: Conference): TOX_CONFERENCE_TYPE =
  proc conference_get_type(


@@ 1268,9 1280,9 @@ proc id*(tox: Tox; conf: Conference): ConferenceId =
  ctoxAssert(true, tox.core.conference_get_id(conf, addr result.bytes[0]))

type Tox_Err_Conference_By_Id = enum
    TOX_ERR_CONFERENCE_BY_ID_OK,
    TOX_ERR_CONFERENCE_BY_ID_NULL,
    TOX_ERR_CONFERENCE_BY_ID_NOT_FOUND
  TOX_ERR_CONFERENCE_BY_ID_OK,
  TOX_ERR_CONFERENCE_BY_ID_NULL,
  TOX_ERR_CONFERENCE_BY_ID_NOT_FOUND

proc conference*(tox: Tox; id: ConferenceId): Conference =
  proc conference_by_id(


@@ 1286,9 1298,9 @@ proc uid*(tox: Tox; conf: Conference): ConferenceUid =
  ctoxAssert(true, tox.core.conference_get_uid(conf, addr result.bytes[0]))

type Tox_Err_Conference_By_Uid = enum
    TOX_ERR_CONFERENCE_BY_UID_OK,
    TOX_ERR_CONFERENCE_BY_UID_NULL,
    TOX_ERR_CONFERENCE_BY_UID_NOT_FOUND
  TOX_ERR_CONFERENCE_BY_UID_OK,
  TOX_ERR_CONFERENCE_BY_UID_NULL,
  TOX_ERR_CONFERENCE_BY_UID_NOT_FOUND

proc conference*(tox: Tox; uid: ConferenceUid): Conference =
  proc conference_by_uid(


@@ 1299,16 1311,17 @@ proc conference*(tox: Tox; uid: ConferenceUid): Conference =
  ctoxAssert(TOX_ERR_CONFERENCE_BY_UID_OK, err)

type Tox_Err_Friend_Custom_Packet = enum
    TOX_ERR_FRIEND_CUSTOM_PACKET_OK,
    TOX_ERR_FRIEND_CUSTOM_PACKET_NULL,
    TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND,
    TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED,
    TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID,
    TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY,
    TOX_ERR_FRIEND_CUSTOM_PACKET_TOO_LONG,
    TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ

proc sendLossyPacket*(tox: Tox; friend: Friend; data: pointer; size: int) {.tags: [IOEffect].} =
  TOX_ERR_FRIEND_CUSTOM_PACKET_OK,
  TOX_ERR_FRIEND_CUSTOM_PACKET_NULL,
  TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND,
  TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED,
  TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID,
  TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY,
  TOX_ERR_FRIEND_CUSTOM_PACKET_TOO_LONG,
  TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ

proc sendLossyPacket*(tox: Tox; friend: Friend; data: pointer; size: int) {.
    tags: [IOEffect].} =
  proc friend_send_lossy_packet(
    core: Core; friend: Friend;
    data: pointer; length: csize;


@@ 1317,7 1330,8 @@ proc sendLossyPacket*(tox: Tox; friend: Friend; data: pointer; size: int) {.tags
  discard tox.core.friend_send_lossy_packet(friend, data, size, addr err)
  ctoxAssert(TOX_ERR_FRIEND_CUSTOM_PACKET_OK, err)

proc sendLosslessPacket*(tox: Tox; friend: Friend; data: pointer; size: int) {.tags: [IOEffect].} =
proc sendLosslessPacket*(tox: Tox; friend: Friend; data: pointer; size: int) {.
    tags: [IOEffect].} =
  proc friend_send_lossless_packet(
    core: Core; friend: Friend;
    data: pointer; length: csize;


@@ 1353,8 1367,8 @@ proc dhtId*(tox: Tox): PublicKey =
  tox.core.self_get_dht_id(addr result.bytes[0])

type Tox_Err_Get_Port = enum
    TOX_ERR_GET_PORT_OK,
    TOX_ERR_GET_PORT_NOT_BOUND
  TOX_ERR_GET_PORT_OK,
  TOX_ERR_GET_PORT_NOT_BOUND

proc udpPort*(tox: Tox): uint16 =
  proc self_get_udp_port(

M tests/simple.nim => tests/simple.nim +1 -1
@@ 14,7 14,7 @@ proc setupCallbacks(bot: Tox) =
    discard bot.addFriendNoRequest(pk)

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


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

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


@@ 9,4 9,4 @@ srcDir        = "src"

# Dependencies

requires "nim >= 0.19.4"
requires "nim >= 1.0.2"