libcwtch-rs: Rust bindings for libcwtch-go
This commit is contained in:
commit
1ead7e597c
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
.idea
|
|
@ -0,0 +1,96 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.98"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libcwtch"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.127"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.127"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.66"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.74"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "libcwtch"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Dan Ballard <dan@mindstab.net>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libc = "0.2"
|
||||||
|
serde_json = "1.0"
|
||||||
|
serde = { version = "1.0.127", features = ["derive"] }
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# libCwtch-rs
|
||||||
|
|
||||||
|
Rust bindings for libCwtch
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
### Updating libCwtch and bingings.rs with Bindgen
|
||||||
|
|
||||||
|
```
|
||||||
|
cargo install bindgen
|
||||||
|
```
|
||||||
|
|
||||||
|
libCwtch.so version is specified in build.rs. If updating, also download the corresponding libCwtch.h and delete
|
||||||
|
the 'preamble from import "C"' section as it imports headers required for the C lib to compile
|
||||||
|
but that we don't want to create rust bindings for (like importing stdlib.h). Then:
|
||||||
|
|
||||||
|
```
|
||||||
|
bindgen libCwtch.h -o src/gobindings/mod.rs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Todo
|
|
@ -0,0 +1,16 @@
|
||||||
|
use std::process::Command;
|
||||||
|
use std::env;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
println!("cargo:rustc-flags=-L {}", out_dir.to_str().unwrap());
|
||||||
|
println!("cargo:rustc-link-lib=Cwtch");
|
||||||
|
|
||||||
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
println!("cargo:rerun-if-changed=libCwtch.h");
|
||||||
|
|
||||||
|
let lib_cwtch_path = Path::new(&out_dir).join("libCwtch.so");
|
||||||
|
// https://git.openprivacy.ca/cwtch.im/libcwtch-go/releases v1.2.0
|
||||||
|
Command::new("wget").arg("https://git.openprivacy.ca/attachments/e77c69f0-9487-4808-bc23-092d943bc4a6").arg("-O").arg(lib_cwtch_path).output().expect("failed to download libCwtch.so");
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
||||||
|
|
||||||
|
/* package git.openprivacy.ca/cwtch.im/libcwtch-go */
|
||||||
|
|
||||||
|
|
||||||
|
#line 1 "cgo-builtin-export-prolog"
|
||||||
|
|
||||||
|
#include <stddef.h> /* for ptrdiff_t below */
|
||||||
|
|
||||||
|
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
||||||
|
#define GO_CGO_EXPORT_PROLOGUE_H
|
||||||
|
|
||||||
|
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||||
|
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Start of boilerplate cgo prologue. */
|
||||||
|
#line 1 "cgo-gcc-export-header-prolog"
|
||||||
|
|
||||||
|
#ifndef GO_CGO_PROLOGUE_H
|
||||||
|
#define GO_CGO_PROLOGUE_H
|
||||||
|
|
||||||
|
typedef signed char GoInt8;
|
||||||
|
typedef unsigned char GoUint8;
|
||||||
|
typedef short GoInt16;
|
||||||
|
typedef unsigned short GoUint16;
|
||||||
|
typedef int GoInt32;
|
||||||
|
typedef unsigned int GoUint32;
|
||||||
|
typedef long long GoInt64;
|
||||||
|
typedef unsigned long long GoUint64;
|
||||||
|
typedef GoInt64 GoInt;
|
||||||
|
typedef GoUint64 GoUint;
|
||||||
|
typedef __SIZE_TYPE__ GoUintptr;
|
||||||
|
typedef float GoFloat32;
|
||||||
|
typedef double GoFloat64;
|
||||||
|
typedef float _Complex GoComplex64;
|
||||||
|
typedef double _Complex GoComplex128;
|
||||||
|
|
||||||
|
/*
|
||||||
|
static assertion to make sure the file is being used on architecture
|
||||||
|
at least with matching size of GoInt.
|
||||||
|
*/
|
||||||
|
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
||||||
|
|
||||||
|
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||||
|
typedef _GoString_ GoString;
|
||||||
|
#endif
|
||||||
|
typedef void *GoMap;
|
||||||
|
typedef void *GoChan;
|
||||||
|
typedef struct { void *t; void *v; } GoInterface;
|
||||||
|
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* End of boilerplate cgo prologue. */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int c_StartCwtch(char* dir_c, int len, char* tor_c, int torLen);
|
||||||
|
extern void c_ReconnectCwtchForeground();
|
||||||
|
|
||||||
|
// A generic method for Rebroadcasting App Events from a UI
|
||||||
|
extern void c_SendAppEvent(char* json_ptr, int json_len);
|
||||||
|
|
||||||
|
// A generic method for Rebroadcasting Profile Events from a UI
|
||||||
|
extern void c_SendProfileEvent(char* onion_ptr, int onion_len, char* json_ptr, int json_len);
|
||||||
|
|
||||||
|
// the pointer returned from this function **must** be freed using c_Free
|
||||||
|
extern char* c_GetAppBusEvent();
|
||||||
|
extern void c_CreateProfile(char* nick_ptr, int nick_len, char* pass_ptr, int pass_len);
|
||||||
|
extern void c_LoadProfiles(char* passwordPtr, int passwordLen);
|
||||||
|
extern void c_AcceptContact(char* profilePtr, int profileLen, char* handlePtr, int handleLen);
|
||||||
|
extern void c_RejectInvite(char* profilePtr, int profileLen, char* handlePtr, int handleLen);
|
||||||
|
extern void c_BlockContact(char* profilePtr, int profileLen, char* handlePtr, int handleLen);
|
||||||
|
extern void c_UpdateMessageFlags(char* profile_ptr, int profile_len, char* handle_ptr, int handle_len, int mIdx, long unsigned int message_flags);
|
||||||
|
|
||||||
|
// the pointer returned from this function **must** be Freed by c_Free
|
||||||
|
extern char* c_GetMessage(char* profile_ptr, int profile_len, char* handle_ptr, int handle_len, int message_index);
|
||||||
|
|
||||||
|
// the pointer returned from this function **must** be freed by calling c_Free
|
||||||
|
extern char* c_GetMessagesByContentHash(char* profile_ptr, int profile_len, char* handle_ptr, int handle_len, char* contenthash_ptr, int contenthash_len);
|
||||||
|
|
||||||
|
// Dangerous function. Should only be used as documented in `MEMORY.md`
|
||||||
|
extern void c_FreePointer(char* ptr);
|
||||||
|
extern void c_SendMessage(char* profile_ptr, int profile_len, char* handle_ptr, int handle_len, char* msg_ptr, int msg_len);
|
||||||
|
extern void c_SendInvitation(char* profile_ptr, int profile_len, char* handle_ptr, int handle_len, char* target_ptr, int target_len);
|
||||||
|
extern void c_ResetTor();
|
||||||
|
extern void c_CreateGroup(char* profile_ptr, int profile_len, char* server_ptr, int server_len, char* name_ptr, int name_len);
|
||||||
|
extern void c_DeleteProfile(char* profile_ptr, int profile_len, char* password_ptr, int password_len);
|
||||||
|
extern void c_ArchiveConversation(char* profile_ptr, int profile_len, char* contact_ptr, int contact_len);
|
||||||
|
extern void c_DeleteContact(char* profile_ptr, int profile_len, char* hanlde_ptr, int handle_len);
|
||||||
|
extern void c_ImportBundle(char* profile_ptr, int profile_len, char* bundle_ptr, int bundle_len);
|
||||||
|
extern void c_SetProfileAttribute(char* profile_ptr, int profile_len, char* key_ptr, int key_len, char* val_ptr, int val_len);
|
||||||
|
extern void c_SetContactAttribute(char* profile_ptr, int profile_len, char* contact_ptr, int contact_len, char* key_ptr, int key_len, char* val_ptr, int val_len);
|
||||||
|
extern void c_SetGroupAttribute(char* profile_ptr, int profile_len, char* group_ptr, int group_len, char* key_ptr, int key_len, char* val_ptr, int val_len);
|
||||||
|
extern void c_ShutdownCwtch();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,118 @@
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::ffi::{CString};
|
||||||
|
use std::ffi::{CStr};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::{CwtchLib};
|
||||||
|
use crate::gobindings;
|
||||||
|
|
||||||
|
struct c_str_wrap {
|
||||||
|
raw: *mut i8,
|
||||||
|
len: i32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl c_str_wrap {
|
||||||
|
pub fn new(str: &str) -> c_str_wrap {
|
||||||
|
let cs = match CString::new(str) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(_) => CString::new("").unwrap()
|
||||||
|
};
|
||||||
|
c_str_wrap { len: cs.as_bytes().len() as i32, raw: cs.into_raw() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for c_str_wrap {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe { CString::from_raw(self.raw); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// c_bind handles setting up c string arguments and freeing them
|
||||||
|
// c_bind!( $fn_name ( [ $string_args ]* ; [ $non_string_args : $type ]* ) $c_function -> $return_type? )
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! c_bind {
|
||||||
|
// macro for returnless fns
|
||||||
|
($func_name:ident ($($str:ident),* ; $($arg:ident: $t:ty),*) $bind_fn:ident) => {
|
||||||
|
fn $func_name(&self, $($str: &str, )* $($arg: $t, )*) {
|
||||||
|
$(let $str = c_str_wrap::new($str);)*
|
||||||
|
unsafe {
|
||||||
|
gobindings::$bind_fn($( $str.raw, $str.len, )* $($arg,)* );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// macro for str returning fns
|
||||||
|
($func_name:ident ($($str:ident),* ; $($arg:ident: $t:ty),* ) $bind_fn:ident -> String) => {
|
||||||
|
fn $func_name(&self, $($str: &str, )* $($arg: $t, )*) -> String {
|
||||||
|
$(let $str = c_str_wrap::new($str);)*
|
||||||
|
unsafe {
|
||||||
|
let result_ptr = gobindings::$bind_fn($( $str.raw, $str.len, )* $($arg,)* );
|
||||||
|
let result = match CStr::from_ptr(result_ptr).to_str() {
|
||||||
|
Ok(s) => s.to_owned(),
|
||||||
|
Err(_) => "".to_string()
|
||||||
|
};
|
||||||
|
// return ownership of string memory and call the library to free it
|
||||||
|
gobindings::c_FreePointer(result_ptr);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// macro for value returning fns
|
||||||
|
($func_name:ident ($($str:ident),* ; $($arg:ident: $t:ty),* ) $bind_fn:ident -> $bind_fn_ty:ty) => {
|
||||||
|
fn $func_name(&self, $($str: &str, )* $($arg: $t, )*) -> $bind_fn_ty {
|
||||||
|
$(let $str = c_str_wrap::new($str);)*
|
||||||
|
unsafe {
|
||||||
|
let result = gobindings::$bind_fn($( $str.raw, $str.len, )* $($arg,)* );
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
struct Event {
|
||||||
|
EventType: String,
|
||||||
|
Data: HashMap<String, String>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GoCwtchLib {}
|
||||||
|
|
||||||
|
impl GoCwtchLib {
|
||||||
|
c_bind!(send_profile_event(profile, event_json;) c_SendProfileEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CwtchLib for GoCwtchLib {
|
||||||
|
c_bind!(start_cwtch(app_dir, tor_path;) c_StartCwtch -> i32);
|
||||||
|
c_bind!(send_app_event(event_json;) c_SendAppEvent);
|
||||||
|
c_bind!(get_appbus_event(;) c_GetAppBusEvent -> String);
|
||||||
|
c_bind!(create_profile(nick, pass;) c_CreateProfile);
|
||||||
|
c_bind!(load_profiles(pass;) c_LoadProfiles);
|
||||||
|
c_bind!(accept_contact(profile, contact;) c_AcceptContact);
|
||||||
|
c_bind!(reject_invite(profile, contact;) c_RejectInvite);
|
||||||
|
c_bind!(block_contact(profile, contact;) c_BlockContact);
|
||||||
|
c_bind!(update_message_flags(profile, contact; message_id: i32, message_flags: u64) c_UpdateMessageFlags);
|
||||||
|
c_bind!(get_message(profile, contact; message_index: i32) c_GetMessage -> String);
|
||||||
|
c_bind!(get_message_by_content_hash(profile, contact, hash;) c_GetMessagesByContentHash -> String);
|
||||||
|
c_bind!(send_message(profile, contact, msg;) c_SendMessage);
|
||||||
|
c_bind!(send_invitation(profile, contact, target;) c_SendInvitation);
|
||||||
|
fn reset_tor(&self) {
|
||||||
|
unsafe { gobindings::c_ResetTor(); }
|
||||||
|
}
|
||||||
|
c_bind!(create_group(profile, server, name;) c_CreateGroup);
|
||||||
|
c_bind!(delete_profile(profile, pass;) c_DeleteProfile);
|
||||||
|
c_bind!(archive_conversation(profile, contact;) c_ArchiveConversation);
|
||||||
|
c_bind!(delete_contact(profile, group;) c_DeleteContact);
|
||||||
|
c_bind!(import_bundle(profile, bundle;) c_ImportBundle);
|
||||||
|
c_bind!(set_profile_attribute(profile, key, val;) c_SetProfileAttribute);
|
||||||
|
c_bind!(set_contact_attribute(profile, contact, key, val;) c_SetContactAttribute);
|
||||||
|
c_bind!(set_group_attribute(profile, group, key, val;) c_SetGroupAttribute);
|
||||||
|
|
||||||
|
fn shutdown_cwtch(&self) {
|
||||||
|
unsafe { gobindings::c_ShutdownCwtch(); }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,399 @@
|
||||||
|
/* automatically generated by rust-bindgen 0.58.1 */
|
||||||
|
|
||||||
|
#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct __BindgenComplex<T> {
|
||||||
|
pub re: T,
|
||||||
|
pub im: T,
|
||||||
|
}
|
||||||
|
pub type size_t = ::std::os::raw::c_ulong;
|
||||||
|
pub type wchar_t = ::std::os::raw::c_int;
|
||||||
|
#[repr(C)]
|
||||||
|
#[repr(align(16))]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct max_align_t {
|
||||||
|
pub __clang_max_align_nonce1: ::std::os::raw::c_longlong,
|
||||||
|
pub __bindgen_padding_0: u64,
|
||||||
|
pub __clang_max_align_nonce2: u128,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_max_align_t() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<max_align_t>(),
|
||||||
|
32usize,
|
||||||
|
concat!("Size of: ", stringify!(max_align_t))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<max_align_t>(),
|
||||||
|
16usize,
|
||||||
|
concat!("Alignment of ", stringify!(max_align_t))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe {
|
||||||
|
&(*(::std::ptr::null::<max_align_t>())).__clang_max_align_nonce1 as *const _ as usize
|
||||||
|
},
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(max_align_t),
|
||||||
|
"::",
|
||||||
|
stringify!(__clang_max_align_nonce1)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe {
|
||||||
|
&(*(::std::ptr::null::<max_align_t>())).__clang_max_align_nonce2 as *const _ as usize
|
||||||
|
},
|
||||||
|
16usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(max_align_t),
|
||||||
|
"::",
|
||||||
|
stringify!(__clang_max_align_nonce2)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct _GoString_ {
|
||||||
|
pub p: *const ::std::os::raw::c_char,
|
||||||
|
pub n: isize,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout__GoString_() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<_GoString_>(),
|
||||||
|
16usize,
|
||||||
|
concat!("Size of: ", stringify!(_GoString_))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<_GoString_>(),
|
||||||
|
8usize,
|
||||||
|
concat!("Alignment of ", stringify!(_GoString_))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(::std::ptr::null::<_GoString_>())).p as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(_GoString_),
|
||||||
|
"::",
|
||||||
|
stringify!(p)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(::std::ptr::null::<_GoString_>())).n as *const _ as usize },
|
||||||
|
8usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(_GoString_),
|
||||||
|
"::",
|
||||||
|
stringify!(n)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pub type GoInt8 = ::std::os::raw::c_schar;
|
||||||
|
pub type GoUint8 = ::std::os::raw::c_uchar;
|
||||||
|
pub type GoInt16 = ::std::os::raw::c_short;
|
||||||
|
pub type GoUint16 = ::std::os::raw::c_ushort;
|
||||||
|
pub type GoInt32 = ::std::os::raw::c_int;
|
||||||
|
pub type GoUint32 = ::std::os::raw::c_uint;
|
||||||
|
pub type GoInt64 = ::std::os::raw::c_longlong;
|
||||||
|
pub type GoUint64 = ::std::os::raw::c_ulonglong;
|
||||||
|
pub type GoInt = GoInt64;
|
||||||
|
pub type GoUint = GoUint64;
|
||||||
|
pub type GoUintptr = ::std::os::raw::c_ulong;
|
||||||
|
pub type GoFloat32 = f32;
|
||||||
|
pub type GoFloat64 = f64;
|
||||||
|
pub type GoComplex64 = __BindgenComplex<f32>;
|
||||||
|
pub type GoComplex128 = __BindgenComplex<f64>;
|
||||||
|
pub type _check_for_64_bit_pointer_matching_GoInt = [::std::os::raw::c_char; 1usize];
|
||||||
|
pub type GoString = _GoString_;
|
||||||
|
pub type GoMap = *mut ::std::os::raw::c_void;
|
||||||
|
pub type GoChan = *mut ::std::os::raw::c_void;
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct GoInterface {
|
||||||
|
pub t: *mut ::std::os::raw::c_void,
|
||||||
|
pub v: *mut ::std::os::raw::c_void,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_GoInterface() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<GoInterface>(),
|
||||||
|
16usize,
|
||||||
|
concat!("Size of: ", stringify!(GoInterface))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<GoInterface>(),
|
||||||
|
8usize,
|
||||||
|
concat!("Alignment of ", stringify!(GoInterface))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(::std::ptr::null::<GoInterface>())).t as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(GoInterface),
|
||||||
|
"::",
|
||||||
|
stringify!(t)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(::std::ptr::null::<GoInterface>())).v as *const _ as usize },
|
||||||
|
8usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(GoInterface),
|
||||||
|
"::",
|
||||||
|
stringify!(v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct GoSlice {
|
||||||
|
pub data: *mut ::std::os::raw::c_void,
|
||||||
|
pub len: GoInt,
|
||||||
|
pub cap: GoInt,
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn bindgen_test_layout_GoSlice() {
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::size_of::<GoSlice>(),
|
||||||
|
24usize,
|
||||||
|
concat!("Size of: ", stringify!(GoSlice))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
::std::mem::align_of::<GoSlice>(),
|
||||||
|
8usize,
|
||||||
|
concat!("Alignment of ", stringify!(GoSlice))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(::std::ptr::null::<GoSlice>())).data as *const _ as usize },
|
||||||
|
0usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(GoSlice),
|
||||||
|
"::",
|
||||||
|
stringify!(data)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(::std::ptr::null::<GoSlice>())).len as *const _ as usize },
|
||||||
|
8usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(GoSlice),
|
||||||
|
"::",
|
||||||
|
stringify!(len)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { &(*(::std::ptr::null::<GoSlice>())).cap as *const _ as usize },
|
||||||
|
16usize,
|
||||||
|
concat!(
|
||||||
|
"Offset of field: ",
|
||||||
|
stringify!(GoSlice),
|
||||||
|
"::",
|
||||||
|
stringify!(cap)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_StartCwtch(
|
||||||
|
dir_c: *mut ::std::os::raw::c_char,
|
||||||
|
len: ::std::os::raw::c_int,
|
||||||
|
tor_c: *mut ::std::os::raw::c_char,
|
||||||
|
torLen: ::std::os::raw::c_int,
|
||||||
|
) -> ::std::os::raw::c_int;
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_ReconnectCwtchForeground();
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_SendAppEvent(json_ptr: *mut ::std::os::raw::c_char, json_len: ::std::os::raw::c_int);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_SendProfileEvent(
|
||||||
|
onion_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
onion_len: ::std::os::raw::c_int,
|
||||||
|
json_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
json_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_GetAppBusEvent() -> *mut ::std::os::raw::c_char;
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_CreateProfile(
|
||||||
|
nick_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
nick_len: ::std::os::raw::c_int,
|
||||||
|
pass_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
pass_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_LoadProfiles(
|
||||||
|
passwordPtr: *mut ::std::os::raw::c_char,
|
||||||
|
passwordLen: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_AcceptContact(
|
||||||
|
profilePtr: *mut ::std::os::raw::c_char,
|
||||||
|
profileLen: ::std::os::raw::c_int,
|
||||||
|
handlePtr: *mut ::std::os::raw::c_char,
|
||||||
|
handleLen: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_RejectInvite(
|
||||||
|
profilePtr: *mut ::std::os::raw::c_char,
|
||||||
|
profileLen: ::std::os::raw::c_int,
|
||||||
|
handlePtr: *mut ::std::os::raw::c_char,
|
||||||
|
handleLen: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_BlockContact(
|
||||||
|
profilePtr: *mut ::std::os::raw::c_char,
|
||||||
|
profileLen: ::std::os::raw::c_int,
|
||||||
|
handlePtr: *mut ::std::os::raw::c_char,
|
||||||
|
handleLen: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_UpdateMessageFlags(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
handle_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
handle_len: ::std::os::raw::c_int,
|
||||||
|
mIdx: ::std::os::raw::c_int,
|
||||||
|
message_flags: ::std::os::raw::c_ulong,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_GetMessage(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
handle_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
handle_len: ::std::os::raw::c_int,
|
||||||
|
message_index: ::std::os::raw::c_int,
|
||||||
|
) -> *mut ::std::os::raw::c_char;
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_GetMessagesByContentHash(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
handle_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
handle_len: ::std::os::raw::c_int,
|
||||||
|
contenthash_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
contenthash_len: ::std::os::raw::c_int,
|
||||||
|
) -> *mut ::std::os::raw::c_char;
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_FreePointer(ptr: *mut ::std::os::raw::c_char);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_SendMessage(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
handle_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
handle_len: ::std::os::raw::c_int,
|
||||||
|
msg_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
msg_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_SendInvitation(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
handle_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
handle_len: ::std::os::raw::c_int,
|
||||||
|
target_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
target_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_ResetTor();
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_CreateGroup(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
server_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
server_len: ::std::os::raw::c_int,
|
||||||
|
name_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
name_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_DeleteProfile(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
password_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
password_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_ArchiveConversation(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
contact_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
contact_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_DeleteContact(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
hanlde_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
handle_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_ImportBundle(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
bundle_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
bundle_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_SetProfileAttribute(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
key_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
key_len: ::std::os::raw::c_int,
|
||||||
|
val_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
val_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_SetContactAttribute(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
contact_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
contact_len: ::std::os::raw::c_int,
|
||||||
|
key_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
key_len: ::std::os::raw::c_int,
|
||||||
|
val_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
val_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_SetGroupAttribute(
|
||||||
|
profile_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
profile_len: ::std::os::raw::c_int,
|
||||||
|
group_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
group_len: ::std::os::raw::c_int,
|
||||||
|
key_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
key_len: ::std::os::raw::c_int,
|
||||||
|
val_ptr: *mut ::std::os::raw::c_char,
|
||||||
|
val_len: ::std::os::raw::c_int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn c_ShutdownCwtch();
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
mod gobindings;
|
||||||
|
mod bindings_go;
|
||||||
|
|
||||||
|
pub mod structs;
|
||||||
|
|
||||||
|
pub trait CwtchLib {
|
||||||
|
fn start_cwtch(&self, app_dir: &str, tor_path: &str) -> i32;
|
||||||
|
fn send_app_event(&self, event_json: &str);
|
||||||
|
fn get_appbus_event(&self, ) -> String;
|
||||||
|
fn create_profile(&self, nick: &str, pass: &str);
|
||||||
|
fn load_profiles(&self, pass: &str);
|
||||||
|
fn accept_contact(&self, profile: &str, contact: &str);
|
||||||
|
fn reject_invite(&self, profile: &str, contact: &str);
|
||||||
|
fn block_contact(&self, profile: &str, contact: &str);
|
||||||
|
fn update_message_flags(&self, profile: &str, contact: &str, message_id: i32, message_flags: u64);
|
||||||
|
fn get_message(&self, profile: &str, contact: &str, message_index: i32) -> String;
|
||||||
|
fn get_message_by_content_hash(&self, profile: &str, contact: &str, hash: &str) -> String;
|
||||||
|
fn send_message(&self, profile: &str, contact: &str, msg: &str);
|
||||||
|
fn send_invitation(&self, profile: &str, contact: &str, target: &str);
|
||||||
|
fn reset_tor(&self, );
|
||||||
|
fn create_group(&self, profile: &str, server: &str, name: &str);
|
||||||
|
fn delete_profile(&self, profile: &str, pass: &str);
|
||||||
|
fn archive_conversation(&self, profile: &str, contact: &str);
|
||||||
|
fn delete_contact(&self, profile: &str, group: &str);
|
||||||
|
fn import_bundle(&self, profile: &str, bundle: &str);
|
||||||
|
fn set_profile_attribute(&self, profile: &str, key: &str, val: &str);
|
||||||
|
fn set_contact_attribute(&self, profile: &str, contact: &str, key: &str, val: &str);
|
||||||
|
fn set_group_attribute(&self, profile: &str, group: &str, key: &str, val: &str);
|
||||||
|
fn shutdown_cwtch(&self, );
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_cwtchlib_go() -> impl CwtchLib {
|
||||||
|
bindings_go::GoCwtchLib {}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct CwtchEvent {
|
||||||
|
pub event_type: String,
|
||||||
|
pub event_ID: String,
|
||||||
|
pub data: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Contact {
|
||||||
|
pub onion: String,
|
||||||
|
pub name: String,
|
||||||
|
pub status: String,
|
||||||
|
pub authorization: String,
|
||||||
|
pub isGroup: bool,
|
||||||
|
//attr: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Server {
|
||||||
|
pub onion: String,
|
||||||
|
pub status: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Profile {
|
||||||
|
pub onion: String,
|
||||||
|
pub nick: String,
|
||||||
|
pub imagePath: String,
|
||||||
|
pub attr: HashMap<String,String>,
|
||||||
|
pub contacts: HashMap<String, Contact>,
|
||||||
|
pub servers: HashMap<String, Server>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Message {
|
||||||
|
pub o: i64,
|
||||||
|
pub d: String
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Profile {
|
||||||
|
pub fn new(identity: &str, name: &str, picture: &str, contacts_json: &str, server_list: &str) -> Profile {
|
||||||
|
let contacts = Profile::process_contacts(contacts_json);
|
||||||
|
let servers = Profile::process_servers(server_list);
|
||||||
|
Profile{ onion: identity.to_string(), nick: name.to_string(), imagePath: picture.to_string(), attr: Default::default(), contacts: contacts, servers: servers }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_contacts(constacts_json: &str) -> HashMap<String, Contact> {
|
||||||
|
let mut contacts: HashMap<String, Contact> = HashMap::new();
|
||||||
|
if constacts_json == "null" {
|
||||||
|
return contacts;
|
||||||
|
}
|
||||||
|
println!("contacts_json: '{}'", constacts_json);
|
||||||
|
let contacts_map: Vec<Contact> = serde_json::from_str(constacts_json).unwrap();
|
||||||
|
for contact in contacts_map {
|
||||||
|
contacts.insert(contact.onion.clone(), contact);
|
||||||
|
}
|
||||||
|
contacts
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_servers(servers_json: &str) -> HashMap<String, Server> {
|
||||||
|
let mut servers: HashMap<String, Server> = HashMap::new();
|
||||||
|
if servers_json == "null" {
|
||||||
|
return servers;
|
||||||
|
}
|
||||||
|
let servers_map: Vec<Server> = serde_json::from_str(servers_json).unwrap();
|
||||||
|
for server in servers_map {
|
||||||
|
servers.insert(server.onion.clone(), server);
|
||||||
|
}
|
||||||
|
servers
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue