mirror of
https://github.com/logos-messaging/nim-chat-poc.git
synced 2026-01-03 22:53:08 +00:00
99 lines
3.1 KiB
Nim
99 lines
3.1 KiB
Nim
## libchat - C bindings for the Chat SDK
|
|
## Main entry point for the shared library
|
|
##
|
|
## This library exposes the Chat SDK functionality through a C-compatible FFI interface.
|
|
## It uses nim-ffi for thread-safe async request handling.
|
|
|
|
import std/[json, options]
|
|
import chronicles, chronos, ffi
|
|
import stew/byteutils
|
|
|
|
import
|
|
../src/chat/client,
|
|
../src/chat/conversations,
|
|
../src/chat/identity,
|
|
../src/chat/delivery/waku_client,
|
|
../src/chat/proto_types,
|
|
./declare_lib,
|
|
./utils
|
|
|
|
logScope:
|
|
topics = "chat ffi"
|
|
|
|
################################################################################
|
|
## Include different APIs, i.e. all procs with {.ffi.} pragma
|
|
include
|
|
./api/client_api,
|
|
./api/conversation_api,
|
|
./api/identity_api
|
|
|
|
################################################################################
|
|
|
|
proc chat_new(
|
|
configJson: cstring, callback: FFICallBack, userData: pointer
|
|
): pointer {.dynlib, exportc, cdecl.} =
|
|
initializeLibrary()
|
|
|
|
## Creates a new instance of the Chat Client.
|
|
if isNil(callback):
|
|
echo "error: missing callback in chat_new"
|
|
return nil
|
|
|
|
## Create the Chat thread that will keep waiting for req from the main thread.
|
|
var ctx = ffi.createFFIContext[Client]().valueOr:
|
|
let msg = "Error in createFFIContext: " & $error
|
|
callback(RET_ERR, unsafeAddr msg[0], cast[csize_t](len(msg)), userData)
|
|
return nil
|
|
|
|
ctx.userData = userData
|
|
|
|
proc onNewMessage(ctx: ptr FFIContext[Client]): MessageCallback =
|
|
return proc(conversation: Conversation, msg: ReceivedMessage): Future[void] {.async.} =
|
|
callEventCallback(ctx, "onNewMessage"):
|
|
$newJsonMessageEvent(
|
|
conversation.id(),
|
|
"",
|
|
msg.content.toHex(),
|
|
msg.timestamp
|
|
)
|
|
|
|
proc onNewConversation(ctx: ptr FFIContext[Client]): NewConvoCallback =
|
|
return proc(conversation: Conversation): Future[void] {.async.} =
|
|
callEventCallback(ctx, "onNewConversation"):
|
|
$newJsonConversationEvent(conversation.id(), "private")
|
|
|
|
proc onDeliveryAck(ctx: ptr FFIContext[Client]): DeliveryAckCallback =
|
|
return proc(conversation: Conversation, msgId: MessageId): Future[void] {.async.} =
|
|
callEventCallback(ctx, "onDeliveryAck"):
|
|
$newJsonDeliveryAckEvent(conversation.id(), msgId)
|
|
|
|
let chatCallbacks = ChatCallbacks(
|
|
onNewMessage: onNewMessage(ctx),
|
|
onNewConversation: onNewConversation(ctx),
|
|
onDeliveryAck: onDeliveryAck(ctx),
|
|
)
|
|
|
|
ffi.sendRequestToFFIThread(
|
|
ctx, CreateClientRequest.ffiNewReq(callback, userData, configJson, chatCallbacks)
|
|
).isOkOr:
|
|
let msg = "error in sendRequestToFFIThread: " & $error
|
|
callback(RET_ERR, unsafeAddr msg[0], cast[csize_t](len(msg)), userData)
|
|
return nil
|
|
|
|
return ctx
|
|
|
|
proc chat_destroy(
|
|
ctx: ptr FFIContext[Client], callback: FFICallBack, userData: pointer
|
|
): cint {.dynlib, exportc, cdecl.} =
|
|
initializeLibrary()
|
|
checkParams(ctx, callback, userData)
|
|
|
|
ffi.destroyFFIContext(ctx).isOkOr:
|
|
let msg = "libchat error: " & $error
|
|
callback(RET_ERR, unsafeAddr msg[0], cast[csize_t](len(msg)), userData)
|
|
return RET_ERR
|
|
|
|
callback(RET_OK, nil, 0, userData)
|
|
|
|
return RET_OK
|