Skip to content

Commit

Permalink
chore(cbindings): cbindings rust simple libwaku integration example (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivansete-status authored Feb 26, 2024
1 parent a1d5cbd commit a499300
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ nimbus-build-system.paths
*.sqlite3-wal

/examples/nodejs/build/
/examples/rust/target/


# Coverage
coverage_html_report/
Expand Down
25 changes: 25 additions & 0 deletions examples/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions examples/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "waku-rust-simple-example"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[build-dependencies]
cc = "1.0.52"
6 changes: 6 additions & 0 deletions examples/rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

This represents a very simple example on how to integrate the `libwaku` library in Rust, and then, only a few `libwaku` functions are being wrapped.

In [waku-rust-bindings](https://github.com/waku-org/waku-rust-bindings) you will find a complete Waku integration in Rust.


5 changes: 5 additions & 0 deletions examples/rust/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

fn main() {
println!("cargo:rustc-link-arg=-lwaku");
println!("cargo:rustc-link-arg=-L../../build/");
}
114 changes: 114 additions & 0 deletions examples/rust/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@

use std::os::raw::{c_char, c_int, c_void};
use std::{slice, thread, time};
use std::cell::OnceCell;
use std::ffi::CString;

pub type WakuCallback =
unsafe extern "C" fn(
c_int,
*const c_char,
usize,
*const c_void,
);

extern "C" {
pub fn waku_new(
config_json: *const u8,
cb: WakuCallback,
user_data: *const c_void,
) -> *mut c_void;

pub fn waku_version(
ctx: *const c_void,
cb: WakuCallback,
user_data: *const c_void,
) -> c_int;

pub fn waku_default_pubsub_topic(
ctx: *mut c_void,
cb: WakuCallback,
user_data: *const c_void,
) -> *mut c_void;
}

pub unsafe extern "C" fn trampoline<C>(
return_val: c_int,
buffer: *const c_char,
buffer_len: usize,
data: *const c_void,
) where
C: FnMut(i32, &str),
{
let closure = &mut *(data as *mut C);

let buffer_utf8 =
String::from_utf8(slice::from_raw_parts(buffer as *mut u8, buffer_len)
.to_vec())
.expect("valid utf8");

closure(return_val, &buffer_utf8);
}

pub fn get_trampoline<C>(_closure: &C) -> WakuCallback
where
C: FnMut(i32, &str),
{
trampoline::<C>
}

fn main() {
let config_json = "\
{ \
\"host\": \"127.0.0.1\",\
\"port\": 60000, \
\"key\": \"0d714a1fada214dead6dc9c7274581ec20ff292451866e7d6d677dc818e8ccd2\", \
\"relay\": true \
}";

unsafe {
// Create the waku node
let closure = |ret: i32, data: &str| {
println!("Ret {ret}. Error creating waku node {data}");
};
let cb = get_trampoline(&closure);
let config_json_str = CString::new(config_json).unwrap();
let ctx = waku_new(
config_json_str.as_ptr() as *const u8,
cb,
&closure as *const _ as *const c_void,
);

// Extracting the current waku version
let version: OnceCell<String> = OnceCell::new();
let closure = |ret: i32, data: &str| {
println!("version_closure. Ret: {ret}. Data: {data}");
let _ = version.set(data.to_string());
};
let cb = get_trampoline(&closure);
let _ret = waku_version(
&ctx as *const _ as *const c_void,
cb,
&closure as *const _ as *const c_void,
);

// Extracting the default pubsub topic
let default_pubsub_topic: OnceCell<String> = OnceCell::new();
let closure = |_ret: i32, data: &str| {
let _ = default_pubsub_topic.set(data.to_string());
};
let cb = get_trampoline(&closure);
let _ret = waku_default_pubsub_topic(
ctx,
cb,
&closure as *const _ as *const c_void,
);

println!("Version: {}", version.get_or_init(|| unreachable!()));
println!("Default pubsubTopic: {}", default_pubsub_topic.get_or_init(|| unreachable!()));
}

loop {
thread::sleep(time::Duration::from_millis(10000));
}
}

0 comments on commit a499300

Please sign in to comment.