Remove convo handles

This commit is contained in:
Jazz Turner-Baggs 2026-02-05 17:49:58 -08:00
parent 1ce196e5ec
commit 8d313880bb
No known key found for this signature in database
6 changed files with 35 additions and 47 deletions

View File

@ -12,7 +12,7 @@ pub enum ErrorCode {
UnknownError = -6, UnknownError = -6,
} }
use crate::context::{Context, ConvoHandle, Introduction}; use crate::context::{Context, Introduction};
/// Opaque wrapper for Context /// Opaque wrapper for Context
#[derive_ReprC] #[derive_ReprC]
@ -74,13 +74,13 @@ pub fn create_new_private_convo(
let Ok(intro) = Introduction::try_from(bundle.as_slice()) else { let Ok(intro) = Introduction::try_from(bundle.as_slice()) else {
return NewConvoResult { return NewConvoResult {
error_code: ErrorCode::BadIntro as i32, error_code: ErrorCode::BadIntro as i32,
convo_id: 0, convo_id: "".into(),
payloads: Vec::new().into(), payloads: Vec::new().into(),
}; };
}; };
// Create conversation // Create conversation
let (convo_handle, payloads) = ctx.0.create_private_convo(&intro, &content); let (convo_id, payloads) = ctx.0.create_private_convo(&intro, &content);
// Convert payloads to FFI-compatible vector // Convert payloads to FFI-compatible vector
let ffi_payloads: Vec<Payload> = payloads let ffi_payloads: Vec<Payload> = payloads
@ -93,7 +93,7 @@ pub fn create_new_private_convo(
NewConvoResult { NewConvoResult {
error_code: 0, error_code: 0,
convo_id: convo_handle, convo_id: convo_id.to_string().into(),
payloads: ffi_payloads.into(), payloads: ffi_payloads.into(),
} }
} }
@ -106,10 +106,10 @@ pub fn create_new_private_convo(
#[ffi_export] #[ffi_export]
pub fn send_content( pub fn send_content(
ctx: &mut ContextHandle, ctx: &mut ContextHandle,
convo_handle: ConvoHandle, convo_id: repr_c::String,
content: c_slice::Ref<'_, u8>, content: c_slice::Ref<'_, u8>,
) -> PayloadResult { ) -> PayloadResult {
let payloads = match ctx.0.send_content(convo_handle, &content) { let payloads = match ctx.0.send_content(&convo_id, &content) {
Ok(p) => p, Ok(p) => p,
Err(_) => { Err(_) => {
return PayloadResult { return PayloadResult {
@ -203,7 +203,7 @@ pub fn destroy_payload_result(result: PayloadResult) {
#[repr(C)] #[repr(C)]
pub struct NewConvoResult { pub struct NewConvoResult {
pub error_code: i32, pub error_code: i32,
pub convo_id: u32, pub convo_id: repr_c::String,
pub payloads: repr_c::Vec<Payload>, pub payloads: repr_c::Vec<Payload>,
} }

View File

@ -1,4 +1,4 @@
use std::{collections::HashMap, rc::Rc, sync::Arc}; use std::rc::Rc;
use crate::{ use crate::{
conversation::{ConversationId, ConversationStore, Convo, Id}, conversation::{ConversationId, ConversationStore, Convo, Id},
@ -9,22 +9,15 @@ use crate::{
types::{AddressedEnvelope, ContentData}, types::{AddressedEnvelope, ContentData},
}; };
pub use crate::conversation::ConversationIdOwned;
pub use crate::inbox::Introduction; pub use crate::inbox::Introduction;
//Offset handles to make debuging easier
const INITIAL_CONVO_HANDLE: u32 = 0xF5000001;
/// Used to identify a conversation on the othersize of the FFI.
pub type ConvoHandle = u32;
// This is the main entry point to the conversations api. // This is the main entry point to the conversations api.
// Ctx manages lifetimes of objects to process and generate payloads. // Ctx manages lifetimes of objects to process and generate payloads.
pub struct Context { pub struct Context {
_identity: Rc<Identity>, _identity: Rc<Identity>,
store: ConversationStore, store: ConversationStore,
inbox: Inbox, inbox: Inbox,
convo_handle_map: HashMap<u32, Arc<str>>,
next_convo_handle: ConvoHandle,
} }
impl Context { impl Context {
@ -35,8 +28,6 @@ impl Context {
_identity: identity, _identity: identity,
store: ConversationStore::new(), store: ConversationStore::new(),
inbox, inbox,
convo_handle_map: HashMap::new(),
next_convo_handle: INITIAL_CONVO_HANDLE,
} }
} }
@ -44,7 +35,7 @@ impl Context {
&mut self, &mut self,
remote_bundle: &Introduction, remote_bundle: &Introduction,
content: &[u8], content: &[u8],
) -> (ConvoHandle, Vec<AddressedEnvelope>) { ) -> (ConversationIdOwned, Vec<AddressedEnvelope>) {
let (convo, payloads) = self let (convo, payloads) = self
.inbox .inbox
.invite_to_private_convo(remote_bundle, content) .invite_to_private_convo(remote_bundle, content)
@ -55,17 +46,17 @@ impl Context {
.map(|p| p.to_envelope(convo.id().to_string())) .map(|p| p.to_envelope(convo.id().to_string()))
.collect(); .collect();
let convo_handle = self.add_convo(Box::new(convo)); let convo_id = self.add_convo(Box::new(convo));
(convo_handle, payload_bytes) (convo_id, payload_bytes)
} }
pub fn send_content( pub fn send_content(
&mut self, &mut self,
convo_handle: ConvoHandle, convo_id: ConversationId,
content: &[u8], content: &[u8],
) -> Result<Vec<AddressedEnvelope>, ChatError> { ) -> Result<Vec<AddressedEnvelope>, ChatError> {
// Lookup convo from handle // Lookup convo from handle
let convo = self.get_convo_mut(convo_handle)?; let convo = self.get_convo_mut(convo_id)?;
// Generate encrypted payloads // Generate encrypted payloads
let payloads = convo.send_message(content)?; let payloads = convo.send_message(content)?;
@ -91,7 +82,7 @@ impl Context {
match convo_id { match convo_id {
c if c == self.inbox.id() => self.dispatch_to_inbox(enc), c if c == self.inbox.id() => self.dispatch_to_inbox(enc),
c if self.store.has(&c) => self.dispatch_to_convo(&c, enc), c if self.store.has(&c) => self.dispatch_to_convo(&c, enc),
_ => Err(ChatError::NoConvo(0)), // TODO: Remove ConvoHandle type _ => Err(ChatError::NoConvo(convo_id)),
} }
} }
@ -123,26 +114,17 @@ impl Context {
Ok(Introduction::from(pkb).into()) Ok(Introduction::from(pkb).into())
} }
fn add_convo(&mut self, convo: Box<dyn Convo>) -> ConvoHandle { fn add_convo(&mut self, convo: Box<dyn Convo>) -> ConversationIdOwned {
let handle = self.next_convo_handle;
self.next_convo_handle += 1;
let convo_id = self.store.insert_convo(convo); let convo_id = self.store.insert_convo(convo);
self.convo_handle_map.insert(handle, convo_id);
handle convo_id
} }
// Returns a mutable reference to a Convo for a given ConvoHandle // Returns a mutable reference to a Convo for a given ConvoId
fn get_convo_mut(&mut self, handle: ConvoHandle) -> Result<&mut dyn Convo, ChatError> { fn get_convo_mut(&mut self, convo_id: ConversationId) -> Result<&mut dyn Convo, ChatError> {
let convo_id = self
.convo_handle_map
.get(&handle)
.ok_or_else(|| ChatError::NoConvo(handle))?
.clone();
self.store self.store
.get_mut(&convo_id) .get_mut(&convo_id)
.ok_or_else(|| ChatError::NoConvo(handle)) .ok_or_else(|| ChatError::NoConvo(convo_id.into()))
} }
} }

View File

@ -19,7 +19,7 @@ pub enum ChatError {
#[error("bytes provided to {0} failed")] #[error("bytes provided to {0} failed")]
BadParsing(&'static str), BadParsing(&'static str),
#[error("convo with handle: {0} was not found")] #[error("convo with handle: {0} was not found")]
NoConvo(u32), NoConvo(String),
} }
#[derive(Error, Debug)] #[derive(Error, Debug)]

View File

@ -24,7 +24,7 @@ proc pingpong() =
echo "Raya's Intro Bundle: ",intro echo "Raya's Intro Bundle: ",intro
var (convo_sr, payloads) = saro.createNewPrivateConvo(intro, encode("Hey Raya")).expect("[Saro] Couldn't create convo") var (convo_sr, payloads) = saro.createNewPrivateConvo(intro, encode("Hey Raya")).expect("[Saro] Couldn't create convo")
echo "ConvoHandle:: ", convo_sr echo "ConvoId:: ", convo_sr
echo "Payload:: ", payloads echo "Payload:: ", payloads
## Send Payloads to Raya ## Send Payloads to Raya

View File

@ -36,7 +36,6 @@ const
# Opaque handle type for Context # Opaque handle type for Context
type ContextHandle* = pointer type ContextHandle* = pointer
type ConvoHandle* = uint32
type type
## Slice for passing byte arrays to safer_ffi functions ## Slice for passing byte arrays to safer_ffi functions
@ -77,7 +76,7 @@ type
## error_code is 0 on success, negative on error (see ErrorCode) ## error_code is 0 on success, negative on error (see ErrorCode)
NewConvoResult* = object NewConvoResult* = object
error_code*: int32 error_code*: int32
convo_id*: uint32 convo_id*: ReprCString
payloads*: VecPayload payloads*: VecPayload
# FFI function imports # FFI function imports
@ -112,7 +111,7 @@ proc create_new_private_convo*(
## The result must be freed with destroy_payload_result() ## The result must be freed with destroy_payload_result()
proc send_content*( proc send_content*(
ctx: ContextHandle, ctx: ContextHandle,
convo_handle: ConvoHandle, convo_id: SliceUint8,
content: SliceUint8, content: SliceUint8,
): PayloadResult {.importc, dynlib: CONVERSATIONS_LIB.} ): PayloadResult {.importc, dynlib: CONVERSATIONS_LIB.}
@ -173,3 +172,10 @@ proc `[]`*(v: VecPayload, i: int): Payload =
## Get length of VecPayload ## Get length of VecPayload
proc len*(v: VecPayload): int = proc len*(v: VecPayload): int =
int(v.len) int(v.len)
## Convert a string to seq[byte]
proc toBytes*(s: string): seq[byte] =
if s.len == 0:
return @[]
result = newSeq[byte](s.len)
copyMem(addr result[0], unsafeAddr s[0], s.len)

View File

@ -46,7 +46,7 @@ proc createIntroductionBundle*(ctx: LibChat): Result[string, string] =
return ok(cast[string](buffer)) return ok(cast[string](buffer))
## Create a Private Convo ## Create a Private Convo
proc createNewPrivateConvo*(ctx: LibChat, bundle: string, content: seq[byte]): Result[(ConvoHandle, seq[PayloadResult]), string] = proc createNewPrivateConvo*(ctx: LibChat, bundle: string, content: seq[byte]): Result[(string, seq[PayloadResult]), string] =
if ctx.handle == nil: if ctx.handle == nil:
return err("Context handle is nil") return err("Context handle is nil")
@ -75,7 +75,7 @@ proc createNewPrivateConvo*(ctx: LibChat, bundle: string, content: seq[byte]): R
data: p.data.toSeq() data: p.data.toSeq()
) )
let convoId = res.convo_id let convoId = $res.convo_id
# Free the result # Free the result
destroy_convo_result(res) destroy_convo_result(res)
@ -83,7 +83,7 @@ proc createNewPrivateConvo*(ctx: LibChat, bundle: string, content: seq[byte]): R
return ok((convoId, payloads)) return ok((convoId, payloads))
## Send content to an existing conversation ## Send content to an existing conversation
proc sendContent*(ctx: LibChat, convoHandle: ConvoHandle, content: seq[byte]): Result[seq[PayloadResult], string] = proc sendContent*(ctx: LibChat, convoId: string, content: seq[byte]): Result[seq[PayloadResult], string] =
if ctx.handle == nil: if ctx.handle == nil:
return err("Context handle is nil") return err("Context handle is nil")
@ -92,7 +92,7 @@ proc sendContent*(ctx: LibChat, convoHandle: ConvoHandle, content: seq[byte]): R
let res = bindings.send_content( let res = bindings.send_content(
ctx.handle, ctx.handle,
convoHandle, convoId.toSlice(),
content.toSlice() content.toSlice()
) )