From 3a685db27f0386a75c6aeddb3ad29e97fdf076b4 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Fri, 15 Jul 2022 12:23:13 -0700 Subject: [PATCH] adding typed types to api part 1 --- src/bindings_go.rs | 154 +++++++++++++++++++++++++++++++++++---------- src/event.rs | 41 ++++++++++++ src/lib.rs | 68 ++++++++++---------- 3 files changed, 196 insertions(+), 67 deletions(-) diff --git a/src/bindings_go.rs b/src/bindings_go.rs index d6b584b..37c4874 100644 --- a/src/bindings_go.rs +++ b/src/bindings_go.rs @@ -8,7 +8,7 @@ use std::ffi::CString; use super::CwtchLib; use crate::cwtchlib_go::bindings; -use crate::{CwtchError, structs::*}; +use crate::{ConversationID, CwtchError, ProfileIdentity, ServerIdentity, structs::*}; use crate::event::Event; struct c_str_wrap { @@ -88,41 +88,111 @@ impl CwtchLibGo { c_bind!(_get_profile_attribute(profile: &str, key: &str;;) c_GetProfileAttribute -> String); c_bind!(_get_conversation_attribute(profile: &str; conversation_id: i32; key: &str) c_GetConversationAttribute -> String); c_bind!(_get_appbus_event(;;) c_GetAppBusEvent -> String); + c_bind!(_send_profile_event(profile: &str, event_jason: &str;;) c_SendProfileEvent); + c_bind!(_accept_conversation(profile: &str ; conversation_id: i32 ;) c_AcceptConversation); + c_bind!(_block_contact(profile: &str ; conversation_id: i32; ) c_BlockContact); + c_bind!(_unblock_contact(profile: &str ; conversation_id: i32; ) c_UnblockContact); + c_bind!(_get_message(profile: &str; conversation_id: i32, message_index: i32 ;) c_GetMessage -> String); + c_bind!(_get_message_by_id(profile: &str ; conversation_id: i32, message_id: i32 ;) c_GetMessageByID -> String); + c_bind!(_get_message_by_content_hash(profile: &str ; conversation_id: i32 ; hash: &str) c_GetMessagesByContentHash -> String); + c_bind!(_get_messages(profile: &str; conversation_id: i32, message_index: i32, count: i32 ;) c_GetMessages -> String); + c_bind!(_send_message(profile: &str; conversation_id: i32; msg: &str) c_SendMessage -> String); + c_bind!(_send_invitation(profile: &str; conversation_id: i32, target_id: i32;) c_SendInvitation -> String); + c_bind!(_share_file(profile: &str; conversation_id: i32; file_path: &str) c_ShareFile -> String); + c_bind!(_download_file(profile: &str; conversation_id: i32; file_path: &str, manifest_path: &str, file_key: &str) c_DownloadFile); + c_bind!(_check_download_status(profile: &str, file_key: &str;;) c_CheckDownloadStatus); + c_bind!(_verify_or_resume_download(profile: &str; conversation_id: i32; file_key: &str) c_VerifyOrResumeDownload); + c_bind!(_create_group(profile: &str, server: &str, name: &str;;) c_CreateGroup); + c_bind!(_delete_profile(profile: &str, pass: &str;;) c_DeleteProfile); + c_bind!(_archive_conversation(profile: &str; conversation_id: i32;) c_ArchiveConversation); + c_bind!(_delete_contact(profile: &str; conversation_id: i32;) c_DeleteContact); + c_bind!(_import_bundle(profile: &str, bundle: &str;;) c_ImportBundle); + c_bind!(_set_profile_attribute(profile: &str, key: &str, val: &str;;) c_SetProfileAttribute); + c_bind!(_set_conversation_attribute(profile: &str; conversation_id: i32; key: &str, val: &str) c_SetConversationAttribute); + c_bind!(_set_message_attribute(profile: &str; conversation_id: i32, channel_id: i32, message_id: i32; key: &str, val: &str) c_SetMessageAttribute); + c_bind!(_change_password(profile: &str, old_pass: &str, new_pass: &str, new_pass_again: &str;;) c_ChangePassword); + c_bind!(_export_profile(profile: &str, filename: &str;;) c_ExportProfile); + c_bind!(_delete_server(server: &str, current_password: &str;;) c_DeleteServer); + c_bind!(_launch_server(server: &str;;) c_LaunchServer); + c_bind!(_stop_server(server: &str;;) c_StopServer); + c_bind!(_set_server_attribute(server: &str, key: &str, val: &str;;) c_SetServerAttribute); } impl CwtchLib for CwtchLibGo { c_bind!(start_cwtch(app_dir: &str, tor_path: &str;;) c_StartCwtch -> i32); c_bind!(started(;;) c_Started -> i32); c_bind!(send_app_event(event_json: &str;;) c_SendAppEvent); - c_bind!(send_profile_event(profile: &str, event_jason: &str;;) c_SendProfileEvent); + fn send_profile_event(&self, profile: ProfileIdentity, event_jason: &str) { + self._send_profile_event(profile.into(), event_jason) + } c_bind!(create_profile(nick: &str, pass: &str;;) c_CreateProfile); c_bind!(load_profiles(pass: &str;;) c_LoadProfiles); - c_bind!(accept_conversation(profile: &str ; conversation_id: i32 ;) c_AcceptConversation); - c_bind!(block_contact(profile: &str ; conversation_id: i32; ) c_BlockContact); - c_bind!(unblock_contact(profile: &str ; conversation_id: i32; ) c_UnblockContact); - c_bind!(get_message(profile: &str; conversation_id: i32, message_index: i32 ;) c_GetMessage -> String); - c_bind!(get_message_by_id(profile: &str ; conversation_id: i32, message_id: i32 ;) c_GetMessageByID -> String); - c_bind!(get_message_by_content_hash(profile: &str ; conversation_id: i32 ; hash: &str) c_GetMessagesByContentHash -> String); - c_bind!(get_messages(profile: &str; conversation_id: i32, message_index: i32, count: i32 ;) c_GetMessages -> String); - c_bind!(send_message(profile: &str; conversation_id: i32; msg: &str) c_SendMessage -> String); - c_bind!(send_invitation(profile: &str; conversation_id: i32, target_id: i32;) c_SendInvitation -> String); - c_bind!(share_file(profile: &str; conversation_id: i32; file_path: &str) c_ShareFile -> String); - c_bind!(download_file(profile: &str; conversation_id: i32; file_path: &str, manifest_path: &str, file_key: &str) c_DownloadFile); - c_bind!(check_download_status(profile: &str, file_key: &str;;) c_CheckDownloadStatus); - c_bind!(verify_or_resume_download(profile: &str; conversation_id: i32; file_key: &str) c_VerifyOrResumeDownload); + fn accept_conversation(&self, profile: ProfileIdentity, conversation_id: ConversationID) { + self._accept_conversation(profile.into(), conversation_id.into()) + } + fn block_contact(&self, profile: ProfileIdentity, conversation_id: ConversationID) { + self._block_contact(profile.into(), conversation_id.into()) + } + fn unblock_contact(&self, profile: ProfileIdentity, conversation_id: ConversationID) { + self._unblock_contact(profile.into(), conversation_id.into()) + } + fn get_message(&self, profile: ProfileIdentity, conversation_id: ConversationID, message_index: i32) -> String { + self._get_message(profile.into(), conversation_id.into(), message_index) + } + fn get_message_by_id(&self, profile: ProfileIdentity, conversation_id: ConversationID, message_id: i32) -> String { + self._get_message_by_id(profile.into(), conversation_id.into(), message_id) + } + fn get_message_by_content_hash(&self, profile: ProfileIdentity, conversation_id: ConversationID, hash: &str) -> String { + self._get_message_by_content_hash(profile.into(), conversation_id.into(), hash) + } + fn get_messages(&self, profile: ProfileIdentity, conversation_id: ConversationID, message_index: i32, count: i32) -> String { + self.get_messages(profile.into(), conversation_id, message_index, count) + } + fn send_message(&self, profile: ProfileIdentity, conversation_id: ConversationID, msg: &str) -> String { + self._send_message(profile.into(), conversation_id.into(), msg) + } + fn send_invitation(&self, profile: ProfileIdentity, conversation_id: ConversationID, target_id: i32) -> String { + self._send_invitation(profile.into(), conversation_id.into(), target_id) + } + fn share_file(&self, profile: ProfileIdentity, conversation_id: ConversationID, file_path: &str) -> String { + self.share_file(profile.into(), conversation_id, file_path) + } + fn download_file(&self, profile: ProfileIdentity, conversation_id: ConversationID, file_path: &str, manifest_path: &str, file_key: &str) { + self._download_file(profile.into(), conversation_id.into(), file_path, manifest_path, file_key) + } + fn check_download_status(&self, profile: ProfileIdentity, file_key: &str) { + self._check_download_status(profile.into(), file_key) + } + fn verify_or_resume_download(&self, profile: ProfileIdentity, conversation_id: ConversationID, file_key: &str) { + self._verify_or_resume_download(profile.into(), conversation_id.into(), file_key) + } + fn reset_tor(&self) { unsafe { bindings::c_ResetTor(); } } - c_bind!(create_group(profile: &str, server: &str, name: &str;;) c_CreateGroup); - c_bind!(delete_profile(profile: &str, pass: &str;;) c_DeleteProfile); - c_bind!(archive_conversation(profile: &str; conversation_id: i32;) c_ArchiveConversation); - c_bind!(delete_contact(profile: &str; conversation_id: i32;) c_DeleteContact); - c_bind!(import_bundle(profile: &str, bundle: &str;;) c_ImportBundle); - c_bind!(set_profile_attribute(profile: &str, key: &str, val: &str;;) c_SetProfileAttribute); - fn get_profile_attribute(&self, profile: &str, key: &str) -> Result, CwtchError> { - let resp = self._get_profile_attribute(profile, key); + fn create_group(&self, profile: ProfileIdentity, server: &str, name: &str) { + self._create_group(profile.into(), server, name) + } + fn delete_profile(&self, profile: ProfileIdentity, pass: &str) { + self._delete_profile(profile.into(), pass) + } + fn archive_conversation(&self, profile: ProfileIdentity, conversation_id: ConversationID) { + self._archive_conversation(profile.into(), conversation_id.into()) + } + fn delete_contact(&self, profile: ProfileIdentity, conversation_id: ConversationID) { + self._delete_contact(profile.into(), conversation_id.into()) + } + fn import_bundle(&self, profile: ProfileIdentity, bundle: &str) { + self._import_bundle(profile.into(), bundle) + } + fn set_profile_attribute(&self, profile: ProfileIdentity, key: &str, val: &str) { + self._set_profile_attribute(profile.into(), key, val) + } + + fn get_profile_attribute(&self, profile: ProfileIdentity, key: &str) -> Result, CwtchError> { + let resp = self._get_profile_attribute(profile.into(), key); let attr: Attribute = match serde_json::from_str(&resp) { Ok(attr) => attr, Err(e) => return Err(e.to_string()), @@ -132,9 +202,11 @@ impl CwtchLib for CwtchLibGo { false => Ok(None), } } - c_bind!(set_conversation_attribute(profile: &str; conversation_id: i32; key: &str, val: &str) c_SetConversationAttribute); - fn get_conversation_attribute(&self, profile: &str, conversation_id: i32, key: &str) -> Result, CwtchError> { - let resp = self._get_conversation_attribute(profile, conversation_id, key); + fn set_conversation_attribute(&self, profile: ProfileIdentity, conversation_id: ConversationID, key: &str, val: &str) { + self._set_conversation_attribute(profile.into(), conversation_id.into(), key, val) + } + fn get_conversation_attribute(&self, profile: ProfileIdentity, conversation_id: ConversationID, key: &str) -> Result, CwtchError> { + let resp = self._get_conversation_attribute(profile.into(), conversation_id.into(), key); let attr: Attribute = match serde_json::from_str(&resp) { Ok(attr) => attr, Err(e) => return Err(e.to_string()), @@ -144,11 +216,19 @@ impl CwtchLib for CwtchLibGo { false => Ok(None), } } - c_bind!(set_message_attribute(profile: &str; conversation_id: i32, channel_id: i32, message_id: i32; key: &str, val: &str) c_SetMessageAttribute); - c_bind!(change_password(profile: &str, old_pass: &str, new_pass: &str, new_pass_again: &str;;) c_ChangePassword); - c_bind!(export_profile(profile: &str, filename: &str;;) c_ExportProfile); + fn set_message_attribute(&self, profile: ProfileIdentity, conversation_id: ConversationID, channel_id: i32, message_id: i32, key: &str, val: &str) { + self._set_message_attribute(profile.into(), conversation_id.into(), channel_id, message_id, key, val) + } + fn change_password(&self, profile: ProfileIdentity, old_pass: &str, new_pass: &str, new_pass_again: &str) { + self._change_password(profile.into(), old_pass, new_pass, new_pass_again) + } + fn export_profile(&self, profile: ProfileIdentity, filename: &str) { + self._export_profile(profile.into(), filename) + } + c_bind!(import_profile(filename: &str, password: &str;;) c_ImportProfile -> String); + fn shutdown_cwtch(&self) { unsafe { bindings::c_ShutdownCwtch(); @@ -157,13 +237,21 @@ impl CwtchLib for CwtchLibGo { c_bind!(load_servers(password: &str;;) c_LoadServers); c_bind!(create_server(password: &str, description: &str; autostart: i8;) c_CreateServer); - c_bind!(delete_server(onion: &str, current_password: &str;;) c_DeleteServer); + fn delete_server(&self, server: ServerIdentity, current_password: &str) { + self._delete_server(server.into(), current_password) + } c_bind!(launch_servers(;;) c_LaunchServers); - c_bind!(launch_server(onion: &str;;) c_LaunchServer); - c_bind!(stop_server(onion: &str;;) c_StopServer); + fn launch_server(&self, server: ServerIdentity) { + self._launch_server(server.into()) + } + fn stop_server(&self, server: ServerIdentity) { + self._stop_server(server.into()) + } c_bind!(stop_servers(;;) c_StopServers); c_bind!(destroy_servers(;;) c_DestroyServers); - c_bind!(set_server_attribute(onion: &str, key: &str, val: &str;;) c_SetServerAttribute); + fn set_server_attribute(&self, server: ServerIdentity, key: &str, val: &str) { + self._set_server_attribute(server.into(), key, val) + } c_bind!(get_debug_info(;;) c_GetDebugInfo -> String); fn get_appbus_event(&self) -> Event { diff --git a/src/event.rs b/src/event.rs index 1a677d9..1e4ba96 100644 --- a/src/event.rs +++ b/src/event.rs @@ -1,3 +1,4 @@ +use std::borrow::Borrow; use std::collections::HashMap; use chrono::{DateTime, FixedOffset}; @@ -18,6 +19,26 @@ impl From for ProfileIdentity { } } +impl From for String { + fn from(x: ProfileIdentity) -> Self { + x.into() + } +} + +impl From<&str> for ProfileIdentity { + fn from(x: &str) -> Self { + ProfileIdentity(x.to_string()) + } +} + +impl From for &str { + fn from(x: ProfileIdentity) -> Self { + //x.0.to_string().as_str() + let s: String = x.0.to_string(); + s.as_str() + } +} + #[derive(Debug)] /// Contact ID used to refer to contacts in Cwtch pub struct ContactIdentity(String); @@ -38,6 +59,12 @@ impl From for ConversationID { } } +impl From for i32 { + fn from(x: ConversationID) -> Self { + x.0 + } +} + #[derive(Debug)] /// Group ID used to refer to a Group in Cwtch pub struct GroupID(String) ; @@ -58,6 +85,20 @@ impl From for ServerIdentity { } } +impl From<&str> for ServerIdentity { + fn from(x: &str) -> Self { + ServerIdentity(x.to_string()) + } +} + +impl From for &str { + fn from(x: ServerIdentity) -> Self { + //x.0.to_string().borrow() + let s: String = x.0.to_string(); + s.as_str() + } +} + #[derive(Debug)] /// FileKey ID user to refer to a file share in Cwtch pub struct FileKey(String); diff --git a/src/lib.rs b/src/lib.rs index b44de4d..c2a225c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ #![doc(html_root_url = "https://git.openprivacy.ca/cwtch.im/libcwtch-rs")] #![deny(missing_docs)] -use crate::event::Event; +use crate::event::{ConversationID, Event, ProfileIdentity, ServerIdentity}; mod bindings_go; mod cwtchlib_go; @@ -28,7 +28,7 @@ pub trait CwtchLib { fn send_app_event(&self, event_json: &str); /// Send json of a structs::CwtchEvent to a cwtch profile - fn send_profile_event(&self, profile: &str, event_json: &str); + fn send_profile_event(&self, profile: ProfileIdentity, event_json: &str); /// Pull json of a structs::CwtchEvent off the appbus for responding to fn get_appbus_event(&self) -> Event; @@ -40,88 +40,88 @@ pub trait CwtchLib { fn load_profiles(&self, pass: &str); /// Cause profile to accept conversation - fn accept_conversation(&self, profile: &str, conversation_id: i32); + fn accept_conversation(&self, profile: ProfileIdentity, conversation_id: ConversationID); /// Cause profile to block conversation - fn block_contact(&self, profile: &str, conversation_id: i32); + fn block_contact(&self, profile: ProfileIdentity, conversation_id: ConversationID); /// Cause profile to unblock contact - fn unblock_contact(&self, profile: &str, conversation_id: i32); + fn unblock_contact(&self, profile: ProfileIdentity, conversation_id: ConversationID); /// Get a specific message for conversation of profile by index - fn get_message(&self, profile: &str, conversation_id: i32, message_index: i32) -> String; + fn get_message(&self, profile: ProfileIdentity, conversation_id: ConversationID, message_index: i32) -> String; /// Get a specific message for a conversation by its id - fn get_message_by_id(&self, profile: &str, conversation_id: i32, message_id: i32) -> String; + fn get_message_by_id(&self, profile: ProfileIdentity, conversation_id: ConversationID, message_id: i32) -> String; /// Get a specific message for conversation of profile by hash fn get_message_by_content_hash( &self, - profile: &str, - conversation_id: i32, + profile: ProfileIdentity, + conversation_id: ConversationID, hash: &str, ) -> String; /// Bulk get messages starting at message index and of count amoung - fn get_messages(&self, profile: &str, conversation_id: i32, message_index: i32, count: i32) -> String; + fn get_messages(&self, profile: ProfileIdentity, conversation_id: ConversationID, message_index: i32, count: i32) -> String; /// Send json of a structs::Message from profile to contact. Returns computed sent message (including index and hash values) - fn send_message(&self, profile: &str, conversation_id: i32, msg: &str) -> String; + fn send_message(&self, profile: ProfileIdentity, conversation_id: ConversationID, msg: &str) -> String; /// Send profile's contact an invite for/to target. Returns computed sent message (including index and hash values) - fn send_invitation(&self, profile: &str, conversation_id: i32, target_id: i32) -> String; + fn send_invitation(&self, profile: ProfileIdentity, conversation_id: ConversationID, target_id: i32) -> String; /// share a file file_path with a conersation. Returns computed sent message (including index and hash values) - fn share_file(&self, profile: &str, conversation_id: i32, file_path: &str) -> String; + fn share_file(&self, profile: ProfileIdentity, conversation_id: ConversationID, file_path: &str) -> String; /// download a file from a conversation to the file_path fn download_file( &self, - profile: &str, - conversation_id: i32, + profile: ProfileIdentity, + conversation_id: ConversationID, file_path: &str, manifest_path: &str, file_key: &str, ); /// Query the status of a download - fn check_download_status(&self, profile: &str, file_key: &str); + fn check_download_status(&self, profile: ProfileIdentity, file_key: &str); /// Verufy a download is done, and if not, resume it - fn verify_or_resume_download(&self, profile: &str, conversation_id: i32, file_key: &str); + fn verify_or_resume_download(&self, profile: ProfileIdentity, conversation_id: ConversationID, file_key: &str); /// Ask the ACN inside the Cwtch app to restart the tor connection fn reset_tor(&self); /// Cause profile to create a group on server with name - fn create_group(&self, profile: &str, server: &str, name: &str); + fn create_group(&self, profile: ProfileIdentity, server: &str, name: &str); /// Delete profile with encryption/password check of pass - fn delete_profile(&self, profile: &str, pass: &str); + fn delete_profile(&self, profile: ProfileIdentity, pass: &str); /// Cause profile to archive conversation with contact - fn archive_conversation(&self, profile: &str, conversation_id: i32); + fn archive_conversation(&self, profile: ProfileIdentity, conversation_id: ConversationID); /// Cause profile to delete contact/group identified by handle - fn delete_contact(&self, profile: &str, conversation_id: i32); + fn delete_contact(&self, profile: ProfileIdentity, conversation_id: ConversationID); /// Cuase profile to attempt to import a contact/group/keybundle identified by bundle - fn import_bundle(&self, profile: &str, bundle: &str); + fn import_bundle(&self, profile: ProfileIdentity, bundle: &str); /// Set a profile attribute key to val - fn set_profile_attribute(&self, profile: &str, key: &str, val: &str); + fn set_profile_attribute(&self, profile: ProfileIdentity, key: &str, val: &str); /// Get a profile attribute - fn get_profile_attribute(&self, profile: &str, key: &str) -> Result, CwtchError>; + fn get_profile_attribute(&self, profile: ProfileIdentity, key: &str) -> Result, CwtchError>; /// Set a profile's contact's attribute of key to val - fn set_conversation_attribute(&self, profile: &str, conversation_id: i32, key: &str, val: &str); + fn set_conversation_attribute(&self, profile: ProfileIdentity, conversation_id: ConversationID, key: &str, val: &str); /// Set an attribute on a message in a conversation fn set_message_attribute( &self, - profile: &str, - conversation_id: i32, + profile: ProfileIdentity, + conversation_id: ConversationID, channel_id: i32, message_id: i32, attribute_key: &str, @@ -129,13 +129,13 @@ pub trait CwtchLib { ); /// Get an attribute for a conversation - fn get_conversation_attribute(&self, profile: &str, conversation_id: i32, key: &str) -> Result, CwtchError>; + fn get_conversation_attribute(&self, profile: ProfileIdentity, conversation_id: ConversationID, key: &str) -> Result, CwtchError>; /// Change a profile's password to new_pass if old_pass is correct - fn change_password(&self, profile: &str, old_pass: &str, new_pass: &str, new_pass_again: &str); + fn change_password(&self, profile: ProfileIdentity, old_pass: &str, new_pass: &str, new_pass_again: &str); /// Export a profile to filename - fn export_profile(&self, profile: &str, filename: &str); + fn export_profile(&self, profile: ProfileIdentity, filename: &str); /// Import a profile from a file with supplied password. Json of a profile struct returned on success fn import_profile(&self, filename: &str, password: &str) -> String; @@ -152,16 +152,16 @@ pub trait CwtchLib { fn create_server(&self, password: &str, description: &str, autostart: i8); /// Delete the specified server (if password is correct) - fn delete_server(&self, onion: &str, current_password: &str); + fn delete_server(&self, server: ServerIdentity, current_password: &str); /// Launch all loaded servers fn launch_servers(&self); /// Launch the specified server - fn launch_server(&self, onion: &str); + fn launch_server(&self, server: ServerIdentity); /// Stop the specified server - fn stop_server(&self, onion: &str); + fn stop_server(&self, server: ServerIdentity); /// Stop all running servers fn stop_servers(&self); @@ -170,7 +170,7 @@ pub trait CwtchLib { fn destroy_servers(&self); /// Set the specified server's attribute of key to val - fn set_server_attribute(&self, onion: &str, key: &str, val: &str); + fn set_server_attribute(&self, server: ServerIdentity, key: &str, val: &str); /// Get debug info (mem, goroutine stats) from lcg in json fn get_debug_info(&self) -> String;