mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-02-09 16:33:10 +00:00
Update Conversation handles over FFI (#46)
* Remove convo handles * Remove convo_handle from docs
This commit is contained in:
parent
1ce196e5ec
commit
135347cdd0
@ -12,7 +12,7 @@ pub enum ErrorCode {
|
||||
UnknownError = -6,
|
||||
}
|
||||
|
||||
use crate::context::{Context, ConvoHandle, Introduction};
|
||||
use crate::context::{Context, Introduction};
|
||||
|
||||
/// Opaque wrapper for Context
|
||||
#[derive_ReprC]
|
||||
@ -74,13 +74,13 @@ pub fn create_new_private_convo(
|
||||
let Ok(intro) = Introduction::try_from(bundle.as_slice()) else {
|
||||
return NewConvoResult {
|
||||
error_code: ErrorCode::BadIntro as i32,
|
||||
convo_id: 0,
|
||||
convo_id: "".into(),
|
||||
payloads: Vec::new().into(),
|
||||
};
|
||||
};
|
||||
|
||||
// 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
|
||||
let ffi_payloads: Vec<Payload> = payloads
|
||||
@ -93,7 +93,7 @@ pub fn create_new_private_convo(
|
||||
|
||||
NewConvoResult {
|
||||
error_code: 0,
|
||||
convo_id: convo_handle,
|
||||
convo_id: convo_id.to_string().into(),
|
||||
payloads: ffi_payloads.into(),
|
||||
}
|
||||
}
|
||||
@ -106,10 +106,10 @@ pub fn create_new_private_convo(
|
||||
#[ffi_export]
|
||||
pub fn send_content(
|
||||
ctx: &mut ContextHandle,
|
||||
convo_handle: ConvoHandle,
|
||||
convo_id: repr_c::String,
|
||||
content: c_slice::Ref<'_, u8>,
|
||||
) -> PayloadResult {
|
||||
let payloads = match ctx.0.send_content(convo_handle, &content) {
|
||||
let payloads = match ctx.0.send_content(&convo_id, &content) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return PayloadResult {
|
||||
@ -203,7 +203,7 @@ pub fn destroy_payload_result(result: PayloadResult) {
|
||||
#[repr(C)]
|
||||
pub struct NewConvoResult {
|
||||
pub error_code: i32,
|
||||
pub convo_id: u32,
|
||||
pub convo_id: repr_c::String,
|
||||
pub payloads: repr_c::Vec<Payload>,
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use std::{collections::HashMap, rc::Rc, sync::Arc};
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{
|
||||
conversation::{ConversationId, ConversationStore, Convo, Id},
|
||||
@ -9,22 +9,15 @@ use crate::{
|
||||
types::{AddressedEnvelope, ContentData},
|
||||
};
|
||||
|
||||
pub use crate::conversation::ConversationIdOwned;
|
||||
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.
|
||||
// Ctx manages lifetimes of objects to process and generate payloads.
|
||||
pub struct Context {
|
||||
_identity: Rc<Identity>,
|
||||
store: ConversationStore,
|
||||
inbox: Inbox,
|
||||
convo_handle_map: HashMap<u32, Arc<str>>,
|
||||
next_convo_handle: ConvoHandle,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
@ -35,8 +28,6 @@ impl Context {
|
||||
_identity: identity,
|
||||
store: ConversationStore::new(),
|
||||
inbox,
|
||||
convo_handle_map: HashMap::new(),
|
||||
next_convo_handle: INITIAL_CONVO_HANDLE,
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +35,7 @@ impl Context {
|
||||
&mut self,
|
||||
remote_bundle: &Introduction,
|
||||
content: &[u8],
|
||||
) -> (ConvoHandle, Vec<AddressedEnvelope>) {
|
||||
) -> (ConversationIdOwned, Vec<AddressedEnvelope>) {
|
||||
let (convo, payloads) = self
|
||||
.inbox
|
||||
.invite_to_private_convo(remote_bundle, content)
|
||||
@ -55,17 +46,17 @@ impl Context {
|
||||
.map(|p| p.to_envelope(convo.id().to_string()))
|
||||
.collect();
|
||||
|
||||
let convo_handle = self.add_convo(Box::new(convo));
|
||||
(convo_handle, payload_bytes)
|
||||
let convo_id = self.add_convo(Box::new(convo));
|
||||
(convo_id, payload_bytes)
|
||||
}
|
||||
|
||||
pub fn send_content(
|
||||
&mut self,
|
||||
convo_handle: ConvoHandle,
|
||||
convo_id: ConversationId,
|
||||
content: &[u8],
|
||||
) -> Result<Vec<AddressedEnvelope>, ChatError> {
|
||||
// Lookup convo from handle
|
||||
let convo = self.get_convo_mut(convo_handle)?;
|
||||
// Lookup convo by id
|
||||
let convo = self.get_convo_mut(convo_id)?;
|
||||
|
||||
// Generate encrypted payloads
|
||||
let payloads = convo.send_message(content)?;
|
||||
@ -91,7 +82,7 @@ impl Context {
|
||||
match convo_id {
|
||||
c if c == self.inbox.id() => self.dispatch_to_inbox(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())
|
||||
}
|
||||
|
||||
fn add_convo(&mut self, convo: Box<dyn Convo>) -> ConvoHandle {
|
||||
let handle = self.next_convo_handle;
|
||||
self.next_convo_handle += 1;
|
||||
fn add_convo(&mut self, convo: Box<dyn Convo>) -> ConversationIdOwned {
|
||||
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
|
||||
fn get_convo_mut(&mut self, handle: ConvoHandle) -> Result<&mut dyn Convo, ChatError> {
|
||||
let convo_id = self
|
||||
.convo_handle_map
|
||||
.get(&handle)
|
||||
.ok_or_else(|| ChatError::NoConvo(handle))?
|
||||
.clone();
|
||||
|
||||
// Returns a mutable reference to a Convo for a given ConvoId
|
||||
fn get_convo_mut(&mut self, convo_id: ConversationId) -> Result<&mut dyn Convo, ChatError> {
|
||||
self.store
|
||||
.get_mut(&convo_id)
|
||||
.ok_or_else(|| ChatError::NoConvo(handle))
|
||||
.ok_or_else(|| ChatError::NoConvo(convo_id.into()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,8 +18,8 @@ pub enum ChatError {
|
||||
InvalidKeyLength,
|
||||
#[error("bytes provided to {0} failed")]
|
||||
BadParsing(&'static str),
|
||||
#[error("convo with handle: {0} was not found")]
|
||||
NoConvo(u32),
|
||||
#[error("convo with id: {0} was not found")]
|
||||
NoConvo(String),
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
||||
@ -24,7 +24,7 @@ proc pingpong() =
|
||||
echo "Raya's Intro Bundle: ",intro
|
||||
|
||||
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
|
||||
|
||||
## Send Payloads to Raya
|
||||
|
||||
@ -36,7 +36,6 @@ const
|
||||
|
||||
# Opaque handle type for Context
|
||||
type ContextHandle* = pointer
|
||||
type ConvoHandle* = uint32
|
||||
|
||||
type
|
||||
## 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)
|
||||
NewConvoResult* = object
|
||||
error_code*: int32
|
||||
convo_id*: uint32
|
||||
convo_id*: ReprCString
|
||||
payloads*: VecPayload
|
||||
|
||||
# FFI function imports
|
||||
@ -112,7 +111,7 @@ proc create_new_private_convo*(
|
||||
## The result must be freed with destroy_payload_result()
|
||||
proc send_content*(
|
||||
ctx: ContextHandle,
|
||||
convo_handle: ConvoHandle,
|
||||
convo_id: SliceUint8,
|
||||
content: SliceUint8,
|
||||
): PayloadResult {.importc, dynlib: CONVERSATIONS_LIB.}
|
||||
|
||||
@ -173,3 +172,10 @@ proc `[]`*(v: VecPayload, i: int): Payload =
|
||||
## Get length of VecPayload
|
||||
proc len*(v: VecPayload): int =
|
||||
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)
|
||||
|
||||
@ -46,7 +46,7 @@ proc createIntroductionBundle*(ctx: LibChat): Result[string, string] =
|
||||
return ok(cast[string](buffer))
|
||||
|
||||
## 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:
|
||||
return err("Context handle is nil")
|
||||
|
||||
@ -75,7 +75,7 @@ proc createNewPrivateConvo*(ctx: LibChat, bundle: string, content: seq[byte]): R
|
||||
data: p.data.toSeq()
|
||||
)
|
||||
|
||||
let convoId = res.convo_id
|
||||
let convoId = $res.convo_id
|
||||
|
||||
# Free the result
|
||||
destroy_convo_result(res)
|
||||
@ -83,7 +83,7 @@ proc createNewPrivateConvo*(ctx: LibChat, bundle: string, content: seq[byte]): R
|
||||
return ok((convoId, payloads))
|
||||
|
||||
## 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:
|
||||
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(
|
||||
ctx.handle,
|
||||
convoHandle,
|
||||
convoId.toSlice(),
|
||||
content.toSlice()
|
||||
)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user