Merge branch 'main' into jazzz/lib_rename

This commit is contained in:
Pablo Lopez 2026-02-22 08:20:22 +02:00 committed by GitHub
commit e90719483b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 63 additions and 18 deletions

View File

@ -49,8 +49,15 @@ pub struct ContextHandle(pub(crate) Context);
/// # Returns
/// Opaque handle to the store. Must be freed with destroy_context()
#[ffi_export]
pub fn create_context() -> repr_c::Box<ContextHandle> {
Box::new(ContextHandle(Context::new())).into()
pub fn create_context(name: repr_c::String) -> repr_c::Box<ContextHandle> {
// Deference name to to `str` and then borrow to &str
Box::new(ContextHandle(Context::new_with_name(&*name))).into()
}
/// Returns the friendly name of the contexts installation.
#[ffi_export]
pub fn installation_name(ctx: &ContextHandle) -> repr_c::String {
ctx.0.installation_name().to_string().into()
}
/// Destroys a conversation store and frees its memory
@ -226,6 +233,7 @@ pub struct HandlePayloadResult {
pub error_code: i32,
pub convo_id: repr_c::String,
pub content: repr_c::Vec<u8>,
pub is_new_convo: bool,
}
/// Free the result from handle_payload
@ -240,6 +248,7 @@ impl From<ContentData> for HandlePayloadResult {
error_code: ErrorCode::None as i32,
convo_id: value.conversation_id.into(),
content: value.data.into(),
is_new_convo: value.is_new_convo,
}
}
}
@ -253,6 +262,7 @@ impl From<Option<ContentData>> for HandlePayloadResult {
error_code: ErrorCode::None as i32,
convo_id: repr_c::String::EMPTY,
content: repr_c::Vec::EMPTY,
is_new_convo: false,
}
}
}
@ -265,6 +275,7 @@ impl From<ChatError> for HandlePayloadResult {
error_code: ErrorCode::UnknownError as i32,
convo_id: String::EMPTY,
content: repr_c::Vec::EMPTY,
is_new_convo: false,
}
}
}

View File

@ -21,8 +21,8 @@ pub struct Context {
}
impl Context {
pub fn new() -> Self {
let identity = Rc::new(Identity::new());
pub fn new_with_name(name: impl Into<String>) -> Self {
let identity = Rc::new(Identity::new(name));
let inbox = Inbox::new(Rc::clone(&identity)); //
Self {
_identity: identity,
@ -31,6 +31,10 @@ impl Context {
}
}
pub fn installation_name(&self) -> &str {
self._identity.get_name()
}
pub fn create_private_convo(
&mut self,
remote_bundle: &Introduction,
@ -156,8 +160,8 @@ mod tests {
#[test]
fn ctx_integration() {
let mut saro = Context::new();
let mut raya = Context::new();
let mut saro = Context::new_with_name("saro");
let mut raya = Context::new_with_name("raya");
// Raya creates intro bundle and sends to Saro
let bundle = raya.create_intro_bundle().unwrap();

View File

@ -3,6 +3,7 @@ use std::fmt;
use crate::crypto::{PrivateKey, PublicKey};
pub struct Identity {
name: String,
secret: PrivateKey,
}
@ -16,8 +17,9 @@ impl fmt::Debug for Identity {
}
impl Identity {
pub fn new() -> Self {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
secret: PrivateKey::random(),
}
}
@ -29,10 +31,17 @@ impl Identity {
pub fn secret(&self) -> &PrivateKey {
&self.secret
}
// Returns an associated name for this Identity.
// Names are a friendly developer chosen identifier for an Identity which
// can provide between logging.
pub fn get_name(&self) -> &str {
&self.name
}
}
impl Default for Identity {
fn default() -> Self {
Self::new()
Self::new("default")
}
}

View File

@ -238,10 +238,10 @@ mod tests {
#[test]
fn test_invite_privatev1_roundtrip() {
let saro_ident = Identity::new();
let saro_ident = Identity::new("saro");
let saro_inbox = Inbox::new(saro_ident.into());
let raya_ident = Identity::new();
let raya_ident = Identity::new("raya");
let mut raya_inbox = Inbox::new(raya_ident.into());
let bundle = raya_inbox.create_intro_bundle();

View File

@ -21,8 +21,8 @@ mod tests {
#[test]
fn test_message_roundtrip() {
let mut saro = create_context();
let mut raya = create_context();
let mut saro = create_context("saro".into());
let mut raya = create_context("raya".into());
// Raya Creates Bundle and Sends to Saro
let intro_result = create_intro_bundle(&mut raya);

3
nim-bindings/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
nimble.develop
nimble.paths
nimbledeps

4
nim-bindings/config.nims Normal file
View File

@ -0,0 +1,4 @@
# begin Nimble config (version 2)
when withDir(thisDir(), system.fileExists("nimble.paths")):
include "nimble.paths"
# end Nimble config

View File

@ -15,8 +15,8 @@ proc encode*(s: string): seq[byte] =
proc pingpong() =
var raya = newConversationsContext()
var saro = newConversationsContext()
var raya = newConversationsContext("raya")
var saro = newConversationsContext("saro")
# Perform out of band Introduction

View File

@ -84,6 +84,7 @@ type
error_code*: int32
convo_id*: ReprCString
content*: VecUint8
is_new_convo*: bool
## Result from create_new_private_convo
## error_code is 0 on success, negative on error (see ErrorCode)
@ -96,7 +97,11 @@ type
## Creates a new libchat Context
## Returns: Opaque handle to the context. Must be freed with destroy_context()
proc create_context*(): ContextHandle {.importc, dynlib: CONVERSATIONS_LIB.}
proc create_context*(name: ReprCString): ContextHandle {.importc, dynlib: CONVERSATIONS_LIB.}
## Returns the friendly name of the context's identity
## The result must be freed by the caller (repr_c::String ownership transfers)
proc installation_name*(ctx: ContextHandle): ReprCString {.importc, dynlib: CONVERSATIONS_LIB.}
## Destroys a context and frees its memory
## - handle must be a valid pointer from create_context()

View File

@ -13,13 +13,20 @@ type
data*: seq[uint8]
## Create a new conversations context
proc newConversationsContext*(): LibChat =
proc newConversationsContext*(name: string): LibChat =
result.handle = create_context()
result.handle = create_context(name.toReprCString)
result.buffer_size = 256
if result.handle.isNil:
raise newException(IOError, "Failed to create context")
## Get the friendly name of this context's installation
proc getInstallationName*(ctx: LibChat): string =
if ctx.handle == nil:
return ""
let name = installation_name(ctx.handle)
result = $name
## Destroy the context and free resources
proc destroy*(ctx: var LibChat) =
@ -114,6 +121,7 @@ type
ContentResult* = object
conversationId*: string
data*: seq[uint8]
isNewConvo*: bool
## Handle an incoming payload and decrypt content
proc handlePayload*(ctx: LibChat, payload: seq[byte]): Result[Option[ContentResult], string] =
@ -141,5 +149,6 @@ proc handlePayload*(ctx: LibChat, payload: seq[byte]): Result[Option[ContentResu
return ok(some(ContentResult(
conversationId: $res.convo_id,
data: content
data: content,
isNewConvo: res.is_new_convo
)))