mirror of
https://github.com/chatmail/core.git
synced 2026-05-19 06:46:32 +03:00
feat: reorg code, and prepare for c bindings
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,4 +2,3 @@
|
|||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
*.db
|
*.db
|
||||||
deltachat.h
|
|
||||||
13
Cargo.toml
13
Cargo.toml
@@ -1,18 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "deltachat-core-rust"
|
name = "deltachat"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["dignifiedquire <dignifiedquire@gmail.com>"]
|
authors = ["dignifiedquire <dignifiedquire@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[lib]
|
|
||||||
name = "deltachat"
|
|
||||||
crate-type = ["cdylib", "staticlib"]
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "1.0.35"
|
cc = "1.0.35"
|
||||||
pkg-config = "0.3"
|
pkg-config = "0.3"
|
||||||
cbindgen = "0.8.3"
|
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
c2rust-bitfields = "0.1.0"
|
c2rust-bitfields = "0.1.0"
|
||||||
@@ -25,3 +19,8 @@ rand = "0.6.5"
|
|||||||
smallvec = "0.6.9"
|
smallvec = "0.6.9"
|
||||||
libsqlite3-sys = "0.14.0"
|
libsqlite3-sys = "0.14.0"
|
||||||
reqwest = "0.9.15"
|
reqwest = "0.9.15"
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"deltachat-ffi"
|
||||||
|
]
|
||||||
12
README.md
12
README.md
@@ -1,3 +1,15 @@
|
|||||||
# Delta Chat Rust
|
# Delta Chat Rust
|
||||||
|
|
||||||
Current commit on deltachat/deltachate-core: `12ef73c8e76185f9b78e844ea673025f56a959ab`.
|
Current commit on deltachat/deltachate-core: `12ef73c8e76185f9b78e844ea673025f56a959ab`.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# run example
|
||||||
|
$ cargo run --example simple
|
||||||
|
# build header file
|
||||||
|
$ cargo build -p deltachat_ffi --release
|
||||||
|
$ cat deltachat-ffi/deltachat.h
|
||||||
|
# run tests
|
||||||
|
$ cargo test --all
|
||||||
|
```
|
||||||
|
|||||||
29
build.rs
29
build.rs
@@ -1,9 +1,5 @@
|
|||||||
extern crate cc;
|
extern crate cc;
|
||||||
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
|
||||||
|
|
||||||
fn link_dylib(lib: &str) {
|
fn link_dylib(lib: &str) {
|
||||||
println!("cargo:rustc-link-lib=dylib={}", lib);
|
println!("cargo:rustc-link-lib=dylib={}", lib);
|
||||||
}
|
}
|
||||||
@@ -31,29 +27,6 @@ fn build_tools() {
|
|||||||
println!("rerun-if-changed=misc.c");
|
println!("rerun-if-changed=misc.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_bindings() {
|
|
||||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
|
||||||
let cfg = cbindgen::Config::from_root_or_default(std::path::Path::new(&crate_dir));
|
|
||||||
let c = cbindgen::Builder::new()
|
|
||||||
.with_config(cfg)
|
|
||||||
.with_crate(crate_dir)
|
|
||||||
.with_header(format!("/* deltachat Header Version {} */", VERSION))
|
|
||||||
// .with_language(cbindgen::Language::C)
|
|
||||||
.generate();
|
|
||||||
|
|
||||||
// This is needed to ensure we don't panic if there are errors in the crates code
|
|
||||||
// but rather just tell the rest of the system we can't proceed.
|
|
||||||
match c {
|
|
||||||
Ok(res) => {
|
|
||||||
res.write_to_file("deltachat.h");
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("unable to generate bindings: {:#?}", err);
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
build_tools();
|
build_tools();
|
||||||
|
|
||||||
@@ -74,6 +47,4 @@ fn main() {
|
|||||||
} else if std::env::var("TARGET").unwrap().contains("linux") {
|
} else if std::env::var("TARGET").unwrap().contains("linux") {
|
||||||
link_dylib("etpan");
|
link_dylib("etpan");
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate_bindings();
|
|
||||||
}
|
}
|
||||||
|
|||||||
5
deltachat-ffi/.gitignore
vendored
Normal file
5
deltachat-ffi/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/target/
|
||||||
|
**/*.rs.bk
|
||||||
|
Cargo.lock
|
||||||
|
.profile
|
||||||
|
*.h
|
||||||
21
deltachat-ffi/Cargo.toml
Normal file
21
deltachat-ffi/Cargo.toml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
[package]
|
||||||
|
name = "deltachat_ffi"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Deltachat FFI"
|
||||||
|
authors = ["dignifiedquire <dignifiedquire@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
readme = "README.md"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
keywords = ["deltachat", "chat", "openpgp", "email", "encryption"]
|
||||||
|
categories = ["cryptography", "std", "email"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib", "staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
deltachat = { path = "../" }
|
||||||
|
libc = "0.2"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
cbindgen = "0.8"
|
||||||
1
deltachat-ffi/README.md
Normal file
1
deltachat-ffi/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# Delta Chat C Interface
|
||||||
23
deltachat-ffi/build.rs
Normal file
23
deltachat-ffi/build.rs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
fn main() {
|
||||||
|
let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||||
|
|
||||||
|
let cfg = cbindgen::Config::from_root_or_default(std::path::Path::new(&crate_dir));
|
||||||
|
|
||||||
|
let c = cbindgen::Builder::new()
|
||||||
|
.with_config(cfg)
|
||||||
|
.with_crate(crate_dir)
|
||||||
|
.with_language(cbindgen::Language::C)
|
||||||
|
.generate();
|
||||||
|
|
||||||
|
// This is needed to ensure we don't panic if there are errors in the crates code
|
||||||
|
// but rather just tell the rest of the system we can't proceed.
|
||||||
|
match c {
|
||||||
|
Ok(res) => {
|
||||||
|
res.write_to_file("deltachat.h");
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("unable to generate bindings: {:#?}", err);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
deltachat-ffi/cbindgen.toml
Normal file
3
deltachat-ffi/cbindgen.toml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[parse]
|
||||||
|
parse_deps = true
|
||||||
|
include = ["deltachat"]
|
||||||
128
deltachat-ffi/src/lib.rs
Normal file
128
deltachat-ffi/src/lib.rs
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
#![allow(
|
||||||
|
non_camel_case_types,
|
||||||
|
non_snake_case,
|
||||||
|
non_upper_case_globals,
|
||||||
|
non_upper_case_globals,
|
||||||
|
non_camel_case_types,
|
||||||
|
non_snake_case
|
||||||
|
)]
|
||||||
|
use deltachat::*;
|
||||||
|
use libc;
|
||||||
|
|
||||||
|
pub const DC_VERSION_STR: &'static str = "0.43.0\x00";
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub type dc_array_t = dc_array::dc_array_t;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_unref(a: *mut dc_array::dc_array_t) {
|
||||||
|
dc_array::dc_array_unref(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_add_uint(array: *mut dc_array_t, item: libc::c_ulong) {
|
||||||
|
dc_array::dc_array_add_uint(array, item)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_add_id(array: *mut dc_array_t, item: libc::c_uint) {
|
||||||
|
dc_array::dc_array_add_id(array, item)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_add_ptr(array: *mut dc_array_t, item: *mut libc::c_void) {
|
||||||
|
dc_array::dc_array_add_ptr(array, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_cnt(array: *const dc_array_t) -> libc::c_ulong {
|
||||||
|
dc_array::dc_array_get_cnt(array)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_uint(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> libc::c_ulong {
|
||||||
|
dc_array::dc_array_get_uint(array, index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_id(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> libc::c_uint {
|
||||||
|
dc_array::dc_array_get_id(array, index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_ptr(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> *mut libc::c_void {
|
||||||
|
dc_array::dc_array_get_ptr(array, index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_latitude(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> libc::c_double {
|
||||||
|
dc_array::dc_array_get_latitude(array, index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_longitude(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> libc::c_double {
|
||||||
|
dc_array::dc_array_get_longitude(array, index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_accuracy(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> libc::c_double {
|
||||||
|
dc_array::dc_array_get_accuracy(array, index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_timestamp(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> libc::c_long {
|
||||||
|
dc_array::dc_array_get_timestamp(array, index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_chat_id(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> libc::c_uint {
|
||||||
|
dc_array::dc_array_get_chat_id(array, index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_contact_id(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> libc::c_uint {
|
||||||
|
dc_array::dc_array_get_contact_id(array, index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_msg_id(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> libc::c_uint {
|
||||||
|
dc_array::dc_array_get_msg_id(array, index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_marker(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
index: libc::c_ulong,
|
||||||
|
) -> *mut libc::c_char {
|
||||||
|
dc_array::dc_array_get_marker(array, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_search_id(
|
||||||
|
array: *const dc_array_t,
|
||||||
|
needle: libc::c_uint,
|
||||||
|
ret_index: *mut libc::c_ulong,
|
||||||
|
) -> libc::c_int {
|
||||||
|
dc_array::dc_array_search_id(array, needle, ret_index)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_array_get_raw(array: *const dc_array_t) -> *const libc::c_ulong {
|
||||||
|
dc_array::dc_array_get_raw(array)
|
||||||
|
}
|
||||||
140
examples/simple.rs
Normal file
140
examples/simple.rs
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
extern crate deltachat;
|
||||||
|
|
||||||
|
use std::ffi::{CStr, CString};
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
use deltachat::constants::Event;
|
||||||
|
use deltachat::dc_chat::*;
|
||||||
|
use deltachat::dc_chatlist::*;
|
||||||
|
use deltachat::dc_configure::*;
|
||||||
|
use deltachat::dc_contact::*;
|
||||||
|
use deltachat::dc_context::*;
|
||||||
|
use deltachat::dc_job::{
|
||||||
|
dc_perform_imap_fetch, dc_perform_imap_idle, dc_perform_imap_jobs, dc_perform_smtp_idle,
|
||||||
|
dc_perform_smtp_jobs,
|
||||||
|
};
|
||||||
|
use deltachat::dc_lot::*;
|
||||||
|
|
||||||
|
fn cb(_ctx: *mut dc_context_t, event: Event, data1: u64, data2: u64) -> u64 {
|
||||||
|
println!("[{:?}]", event);
|
||||||
|
|
||||||
|
match event {
|
||||||
|
Event::HTTP_GET => {
|
||||||
|
let url = unsafe { CStr::from_ptr(data1 as *const _).to_str().unwrap() };
|
||||||
|
|
||||||
|
match reqwest::get(url) {
|
||||||
|
Ok(ref mut res) => {
|
||||||
|
let c_res = CString::new(res.text().unwrap()).unwrap();
|
||||||
|
// need to use strdup to allocate the result with malloc
|
||||||
|
// so it can be `free`d later.
|
||||||
|
unsafe { libc::strdup(c_res.as_ptr()) as u64 }
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
println!("failed to download: {}: {:?}", url, err);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::INFO | Event::WARNING | Event::ERROR => {
|
||||||
|
println!(
|
||||||
|
" {}",
|
||||||
|
unsafe { CStr::from_ptr(data2 as *const _) }
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
_ => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Wrapper(NonNull<dc_context_t>);
|
||||||
|
|
||||||
|
unsafe impl std::marker::Send for Wrapper {}
|
||||||
|
unsafe impl std::marker::Sync for Wrapper {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
let ctx = dc_context_new(Some(cb), std::ptr::null_mut(), std::ptr::null_mut());
|
||||||
|
let info = dc_get_info(ctx);
|
||||||
|
let info_s = CStr::from_ptr(info);
|
||||||
|
println!("info: {}", info_s.to_str().unwrap());
|
||||||
|
|
||||||
|
let sendable_ctx = Wrapper(NonNull::new(ctx).unwrap());
|
||||||
|
let t1 = std::thread::spawn(move || loop {
|
||||||
|
dc_perform_imap_jobs(sendable_ctx.0.as_ptr());
|
||||||
|
dc_perform_imap_fetch(sendable_ctx.0.as_ptr());
|
||||||
|
dc_perform_imap_idle(sendable_ctx.0.as_ptr());
|
||||||
|
});
|
||||||
|
|
||||||
|
let sendable_ctx = Wrapper(NonNull::new(ctx).unwrap());
|
||||||
|
let t2 = std::thread::spawn(move || loop {
|
||||||
|
dc_perform_smtp_jobs(sendable_ctx.0.as_ptr());
|
||||||
|
dc_perform_smtp_idle(sendable_ctx.0.as_ptr());
|
||||||
|
});
|
||||||
|
|
||||||
|
let dbfile = CString::new("../deltachat-core/build/hello2.db").unwrap();
|
||||||
|
println!("opening dir");
|
||||||
|
dc_open(ctx, dbfile.as_ptr(), std::ptr::null());
|
||||||
|
|
||||||
|
if dc_is_configured(ctx) == 0 {
|
||||||
|
println!("configuring");
|
||||||
|
dc_set_config(
|
||||||
|
ctx,
|
||||||
|
CString::new("addr").unwrap().as_ptr(),
|
||||||
|
CString::new("d@testrun.org").unwrap().as_ptr(),
|
||||||
|
);
|
||||||
|
dc_set_config(
|
||||||
|
ctx,
|
||||||
|
CString::new("mail_pw").unwrap().as_ptr(),
|
||||||
|
CString::new("***").unwrap().as_ptr(),
|
||||||
|
);
|
||||||
|
dc_configure(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread::sleep_ms(4000);
|
||||||
|
|
||||||
|
let email = CString::new("dignifiedquire@gmail.com").unwrap();
|
||||||
|
println!("sending a message");
|
||||||
|
let contact_id = dc_create_contact(ctx, std::ptr::null(), email.as_ptr());
|
||||||
|
let chat_id = dc_create_chat_by_contact_id(ctx, contact_id);
|
||||||
|
let msg_text = CString::new("Hi, here is my first message!").unwrap();
|
||||||
|
dc_send_text_msg(ctx, chat_id, msg_text.as_ptr());
|
||||||
|
|
||||||
|
println!("fetching chats..");
|
||||||
|
let chats = dc_get_chatlist(ctx, 0, std::ptr::null(), 0);
|
||||||
|
|
||||||
|
for i in 0..dc_chatlist_get_cnt(chats) {
|
||||||
|
let summary = dc_chatlist_get_summary(chats, 0, std::ptr::null_mut());
|
||||||
|
let text1 = dc_lot_get_text1(summary);
|
||||||
|
let text2 = dc_lot_get_text2(summary);
|
||||||
|
|
||||||
|
let text1_s = if !text1.is_null() {
|
||||||
|
Some(CStr::from_ptr(text1))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let text2_s = if !text2.is_null() {
|
||||||
|
Some(CStr::from_ptr(text2))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
println!("chat: {} - {:?} - {:?}", i, text1_s, text2_s,);
|
||||||
|
dc_lot_unref(summary);
|
||||||
|
}
|
||||||
|
dc_chatlist_unref(chats);
|
||||||
|
|
||||||
|
// let msglist = dc_get_chat_msgs(ctx, chat_id, 0, 0);
|
||||||
|
// for i in 0..dc_array_get_cnt(msglist) {
|
||||||
|
// let msg_id = dc_array_get_id(msglist, i);
|
||||||
|
// let msg = dc_get_msg(context, msg_id);
|
||||||
|
// let text = CStr::from_ptr(dc_msg_get_text(msg)).unwrap();
|
||||||
|
// println!("Message {}: {}\n", i + 1, text.to_str().unwrap());
|
||||||
|
// dc_msg_unref(msg);
|
||||||
|
// }
|
||||||
|
// dc_array_unref(msglist);
|
||||||
|
|
||||||
|
t1.join().unwrap();
|
||||||
|
t2.join().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
1
rustfmt.toml
Normal file
1
rustfmt.toml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
edition = "2018"
|
||||||
143
src/lib.rs
143
src/lib.rs
@@ -69,146 +69,3 @@ pub mod types;
|
|||||||
|
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
pub use self::constants::*;
|
pub use self::constants::*;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use std::ffi::{CStr, CString};
|
|
||||||
use std::ptr::NonNull;
|
|
||||||
|
|
||||||
use crate::constants::Event;
|
|
||||||
use crate::dc_chat::*;
|
|
||||||
use crate::dc_chatlist::*;
|
|
||||||
use crate::dc_configure::*;
|
|
||||||
use crate::dc_contact::*;
|
|
||||||
use crate::dc_context::*;
|
|
||||||
use crate::dc_job::{
|
|
||||||
dc_perform_imap_fetch, dc_perform_imap_idle, dc_perform_imap_jobs, dc_perform_smtp_idle,
|
|
||||||
dc_perform_smtp_jobs,
|
|
||||||
};
|
|
||||||
use crate::dc_lot::*;
|
|
||||||
|
|
||||||
fn cb(_ctx: *mut dc_context_t, event: Event, data1: u64, data2: u64) -> u64 {
|
|
||||||
println!("[{:?}]", event);
|
|
||||||
|
|
||||||
match event {
|
|
||||||
Event::HTTP_GET => {
|
|
||||||
let url = unsafe { CStr::from_ptr(data1 as *const _).to_str().unwrap() };
|
|
||||||
|
|
||||||
match reqwest::get(url) {
|
|
||||||
Ok(ref mut res) => {
|
|
||||||
let c_res = CString::new(res.text().unwrap()).unwrap();
|
|
||||||
// need to use strdup to allocate the result with malloc
|
|
||||||
// so it can be `free`d later.
|
|
||||||
unsafe { libc::strdup(c_res.as_ptr()) as u64 }
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
println!("failed to download: {}: {:?}", url, err);
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Event::INFO | Event::WARNING | Event::ERROR => {
|
|
||||||
println!(
|
|
||||||
" {}",
|
|
||||||
unsafe { CStr::from_ptr(data2 as *const _) }
|
|
||||||
.to_str()
|
|
||||||
.unwrap()
|
|
||||||
);
|
|
||||||
0
|
|
||||||
}
|
|
||||||
_ => 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Wrapper(NonNull<dc_context_t>);
|
|
||||||
|
|
||||||
unsafe impl std::marker::Send for Wrapper {}
|
|
||||||
unsafe impl std::marker::Sync for Wrapper {}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_basics() {
|
|
||||||
unsafe {
|
|
||||||
let mut ctx = dc_context_new(Some(cb), std::ptr::null_mut(), std::ptr::null_mut());
|
|
||||||
let info = dc_get_info(ctx);
|
|
||||||
let info_s = CStr::from_ptr(info);
|
|
||||||
println!("info: {}", info_s.to_str().unwrap());
|
|
||||||
|
|
||||||
let sendable_ctx = Wrapper(NonNull::new(ctx).unwrap());
|
|
||||||
let t1 = std::thread::spawn(move || loop {
|
|
||||||
dc_perform_imap_jobs(sendable_ctx.0.as_ptr());
|
|
||||||
dc_perform_imap_fetch(sendable_ctx.0.as_ptr());
|
|
||||||
dc_perform_imap_idle(sendable_ctx.0.as_ptr());
|
|
||||||
});
|
|
||||||
|
|
||||||
let sendable_ctx = Wrapper(NonNull::new(ctx).unwrap());
|
|
||||||
let t2 = std::thread::spawn(move || loop {
|
|
||||||
dc_perform_smtp_jobs(sendable_ctx.0.as_ptr());
|
|
||||||
dc_perform_smtp_idle(sendable_ctx.0.as_ptr());
|
|
||||||
});
|
|
||||||
|
|
||||||
let dbfile = CString::new("../deltachat-core/build/hello2.db").unwrap();
|
|
||||||
println!("opening dir");
|
|
||||||
dc_open(ctx, dbfile.as_ptr(), std::ptr::null());
|
|
||||||
|
|
||||||
if dc_is_configured(ctx) == 0 {
|
|
||||||
println!("configuring");
|
|
||||||
dc_set_config(
|
|
||||||
ctx,
|
|
||||||
CString::new("addr").unwrap().as_ptr(),
|
|
||||||
CString::new("d@testrun.org").unwrap().as_ptr(),
|
|
||||||
);
|
|
||||||
dc_set_config(
|
|
||||||
ctx,
|
|
||||||
CString::new("mail_pw").unwrap().as_ptr(),
|
|
||||||
CString::new("***").unwrap().as_ptr(),
|
|
||||||
);
|
|
||||||
dc_configure(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::thread::sleep_ms(4000);
|
|
||||||
|
|
||||||
let email = CString::new("dignifiedquire@gmail.com").unwrap();
|
|
||||||
println!("sending a message");
|
|
||||||
let contact_id = dc_create_contact(ctx, std::ptr::null(), email.as_ptr());
|
|
||||||
let chat_id = dc_create_chat_by_contact_id(ctx, contact_id);
|
|
||||||
let msg_text = CString::new("Hi, here is my first message!").unwrap();
|
|
||||||
dc_send_text_msg(ctx, chat_id, msg_text.as_ptr());
|
|
||||||
|
|
||||||
println!("fetching chats..");
|
|
||||||
let chats = dc_get_chatlist(ctx, 0, std::ptr::null(), 0);
|
|
||||||
|
|
||||||
for i in 0..dc_chatlist_get_cnt(chats) {
|
|
||||||
let summary = dc_chatlist_get_summary(chats, 0, std::ptr::null_mut());
|
|
||||||
let text1 = dc_lot_get_text1(summary);
|
|
||||||
let text2 = dc_lot_get_text2(summary);
|
|
||||||
|
|
||||||
let text1_s = if !text1.is_null() {
|
|
||||||
Some(CStr::from_ptr(text1))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let text2_s = if !text2.is_null() {
|
|
||||||
Some(CStr::from_ptr(text2))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
println!("chat: {} - {:?} - {:?}", i, text1_s, text2_s,);
|
|
||||||
dc_lot_unref(summary);
|
|
||||||
}
|
|
||||||
dc_chatlist_unref(chats);
|
|
||||||
|
|
||||||
// let msglist = dc_get_chat_msgs(ctx, chat_id, 0, 0);
|
|
||||||
// for i in 0..dc_array_get_cnt(msglist) {
|
|
||||||
// let msg_id = dc_array_get_id(msglist, i);
|
|
||||||
// let msg = dc_get_msg(context, msg_id);
|
|
||||||
// let text = CStr::from_ptr(dc_msg_get_text(msg)).unwrap();
|
|
||||||
// println!("Message {}: {}\n", i + 1, text.to_str().unwrap());
|
|
||||||
// dc_msg_unref(msg);
|
|
||||||
// }
|
|
||||||
// dc_array_unref(msglist);
|
|
||||||
|
|
||||||
t1.join().unwrap();
|
|
||||||
t2.join().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user