nim-chat-sdk/chat_sdk/chat_sdk.nim
2025-06-10 15:48:29 +03:00

116 lines
3.7 KiB
Nim

import std/[times]
# Storage interface function pointer types
type
StoreMessageProc* = proc(id: cstring, message: cstring, userData: pointer): cint {.cdecl.}
GetMessageProc* = proc(id: cstring, userData: pointer): cstring {.cdecl.}
# ChatSDK object
type
ChatSDK* = object
storeCallback: StoreMessageProc
getCallback: GetMessageProc
userData: pointer # For Go-side data if needed
# Create a new ChatSDK instance
proc newChatSDK*(storeProc: StoreMessageProc, getProc: GetMessageProc, userData: pointer = nil): ChatSDK =
ChatSDK(
storeCallback: storeProc,
getCallback: getProc,
userData: userData
)
# Send message method for ChatSDK
proc sendMessage*(sdk: ChatSDK, id: string, message: string): bool =
## Sends a message by printing it to stdout with timestamp and storing it
let timestamp = now()
echo "[", timestamp.format("yyyy-MM-dd HH:mm:ss"), "] ChatSDK: ", message
# Store the message using the provided storage interface
if sdk.storeCallback != nil:
let storeResult = sdk.storeCallback(cstring(id), cstring(message), sdk.userData)
return storeResult == 0
return false
# Get message method for ChatSDK
proc getMessage*(sdk: ChatSDK, id: string): string =
## Gets a message using the provided storage interface
if sdk.getCallback != nil:
let messageResult = sdk.getCallback(cstring(id), sdk.userData)
if messageResult != nil:
return $messageResult
return ""
# Original standalone sendMessage for backward compatibility
proc sendMessage*(message: string) =
## Sends a message by printing it to stdout with timestamp
let timestamp = now()
echo "[", timestamp.format("yyyy-MM-dd HH:mm:ss"), "] ChatSDK: ", message
# C-compatible wrappers
proc sendMessageCString*(message: cstring): cint {.exportc, dynlib.} =
## C-compatible wrapper for standalone sendMessage
try:
sendMessage($message)
return 0 # Success
except:
return 1 # Error
proc newChatSDKC*(storeProc: StoreMessageProc, getProc: GetMessageProc, userData: pointer = nil): ptr ChatSDK {.exportc, dynlib.} =
## C-compatible wrapper to create a new ChatSDK instance
try:
let sdk = newChatSDK(storeProc, getProc, userData)
let sdkPtr = cast[ptr ChatSDK](alloc(sizeof(ChatSDK)))
sdkPtr[] = sdk
return sdkPtr
except:
return nil
proc freeChatSDKC*(sdk: ptr ChatSDK) {.exportc, dynlib.} =
## C-compatible wrapper to free ChatSDK instance
if sdk != nil:
dealloc(sdk)
proc sendMessageSDKC*(sdk: ptr ChatSDK, id: cstring, message: cstring): cint {.exportc, dynlib.} =
## C-compatible wrapper for ChatSDK sendMessage
try:
if sdk == nil:
return 1
let success = sdk[].sendMessage($id, $message)
return if success: 0 else: 1
except:
return 1
proc getMessageSDKC*(sdk: ptr ChatSDK, id: cstring): cstring {.exportc, dynlib.} =
## C-compatible wrapper for ChatSDK getMessage
try:
if sdk == nil:
return nil
let message = sdk[].getMessage($id) # Convert cstring to string for internal method
if message.len > 0:
# Allocate C string - caller must free
let cStr = cast[cstring](alloc(message.len + 1))
copyMem(cStr, cstring(message), message.len + 1)
return cStr
return nil
except:
return nil
proc freeCString*(str: cstring) {.exportc, dynlib.} =
## Free a C string allocated by the library
if str != nil:
dealloc(str)
# Export the module for C bindings
when isMainModule:
sendMessage("Test message from Nim!")
# This is just an example to get you started. A typical library package
# exports the main API in this file. Note that you cannot rename this file
# but you can remove it if you wish.
proc add*(x, y: int): int =
## Adds two numbers together.
return x + y