mirror of
https://github.com/logos-messaging/logos-messaging-rust-bindings.git
synced 2026-08-26 16:01:08 +00:00
feat!: expose the generated bindings, drop the hand-written FFI tier
The generated crate already provides what this tier existed to build: CBOR marshalling, the callback dance, and a typed method per proc. So macros.rs (trampoline, handle_ffi_call) and libwaku_response.rs (RET_OK/RET_ERR, LibwakuResponse) are deleted rather than ported, and node/events.rs goes with them -- its WakuEvent enum is now one generated payload struct per event, which is what the typed listeners hand back. What survives is what the generated crate does not give us: the domain layer (WakuMessage, WakuContentTopic, MessageHash, pubsubtopic) and WakuNodeConfig, which still serialises to the JSON create_node takes -- that JSON is unchanged, only its transport moved to CBOR. BREAKING CHANGE: WakuNodeHandle and its Initialized/Running typestate, waku_new, and waku_destroy are gone; callers use LogosDeliveryCtx::create and let Drop tear the node down. set_event_callback is gone too: events are per-name now, so a whole-stream callback has no equivalent -- use the typed add_on_*_listener methods, which deliver a payload struct instead of a JSON string to match on. Tests and the example move with the API. The event handling gets shorter rather than longer: no from_str, no matching five variants, no panicking on Unrecognized -- a listener only receives the event it registered for. Callers now base64-decode payloads themselves, since that was WakuMessage's serde doing it before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
98d005c9e1
commit
430ebc0bda
@@ -11,3 +11,4 @@ tokio = { version = "1.36.0", features = ["full"] }
|
||||
tokio-util = { version = "0.7.10", features = ["rt"] }
|
||||
waku = { path = "../../waku-bindings", package = "waku-bindings" }
|
||||
serde_json = "1.0"
|
||||
base64 = "0.21"
|
||||
|
||||
+48
-87
@@ -1,101 +1,60 @@
|
||||
use base64::Engine;
|
||||
use std::io::Error;
|
||||
use std::str::from_utf8;
|
||||
use tokio::time::{sleep, Duration};
|
||||
use waku::{
|
||||
general::pubsubtopic::PubsubTopic, waku_new, Encoding, LibwakuResponse, WakuContentTopic,
|
||||
WakuEvent, WakuMessage, WakuNodeConfig,
|
||||
Encoding, LogosDeliveryCtx, ReceivedMessagePayload, WakuContentTopic, WakuMessage,
|
||||
WakuNodeConfig,
|
||||
};
|
||||
|
||||
const TOPIC: &str = "test";
|
||||
const TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
fn new_node(tcp_port: usize) -> LogosDeliveryCtx {
|
||||
let config = serde_json::to_string(&WakuNodeConfig {
|
||||
tcp_port: Some(tcp_port),
|
||||
..Default::default()
|
||||
})
|
||||
.expect("config should serialise");
|
||||
|
||||
LogosDeliveryCtx::create(config, TIMEOUT).expect("should instantiate")
|
||||
}
|
||||
|
||||
fn print_received(node_name: &'static str) -> impl Fn(&ReceivedMessagePayload) {
|
||||
move |event| {
|
||||
let payload = base64::engine::general_purpose::STANDARD
|
||||
.decode(&event.waku_message.payload)
|
||||
.expect("payload should be base64");
|
||||
let msg = from_utf8(&payload).expect("should be valid message");
|
||||
println!("::::::::::::::::::::::::::::::::::::::::::::::::::::");
|
||||
println!("Message Received in {node_name}: {msg}");
|
||||
println!("::::::::::::::::::::::::::::::::::::::::::::::::::::");
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Error> {
|
||||
let node1 = waku_new(Some(WakuNodeConfig {
|
||||
tcp_port: Some(60010), // TODO: use any available port.
|
||||
..Default::default()
|
||||
}))
|
||||
.await
|
||||
.expect("should instantiate");
|
||||
|
||||
let node2 = waku_new(Some(WakuNodeConfig {
|
||||
tcp_port: Some(60020), // TODO: use any available port.
|
||||
..Default::default()
|
||||
}))
|
||||
.await
|
||||
.expect("should instantiate");
|
||||
let node1 = new_node(60010); // TODO: use any available port.
|
||||
let node2 = new_node(60020); // TODO: use any available port.
|
||||
|
||||
// ========================================================================
|
||||
// Setting an event callback to be executed each time a message is received
|
||||
node2
|
||||
.set_event_callback(|response| {
|
||||
if let LibwakuResponse::Success(v) = response {
|
||||
let event: WakuEvent =
|
||||
serde_json::from_str(v.unwrap().as_str()).expect("Parsing event to succeed");
|
||||
// Registering a listener to be executed each time a message is received
|
||||
node2.add_on_received_message_listener(print_received("NODE 2"));
|
||||
node1.add_on_received_message_listener(print_received("NODE 1"));
|
||||
|
||||
match event {
|
||||
WakuEvent::WakuMessage(evt) => {
|
||||
// println!("WakuMessage event received: {:?}", evt.waku_message);
|
||||
let message = evt.waku_message;
|
||||
let payload = message.payload.to_vec();
|
||||
let msg = from_utf8(&payload).expect("should be valid message");
|
||||
println!("::::::::::::::::::::::::::::::::::::::::::::::::::::");
|
||||
println!("Message Received in NODE 2: {}", msg);
|
||||
println!("::::::::::::::::::::::::::::::::::::::::::::::::::::");
|
||||
}
|
||||
WakuEvent::RelayTopicHealthChange(_evt) => {
|
||||
// dbg!("Relay topic change evt", evt);
|
||||
}
|
||||
WakuEvent::ConnectionChange(_evt) => {
|
||||
// dbg!("Conn change evt", evt);
|
||||
}
|
||||
WakuEvent::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err),
|
||||
_ => panic!("event case not expected"),
|
||||
};
|
||||
}
|
||||
})
|
||||
.expect("set event call back working");
|
||||
|
||||
node1
|
||||
.set_event_callback(|response| {
|
||||
if let LibwakuResponse::Success(v) = response {
|
||||
let event: WakuEvent =
|
||||
serde_json::from_str(v.unwrap().as_str()).expect("Parsing event to succeed");
|
||||
|
||||
match event {
|
||||
WakuEvent::WakuMessage(evt) => {
|
||||
// println!("WakuMessage event received: {:?}", evt.waku_message);
|
||||
let message = evt.waku_message;
|
||||
let payload = message.payload.to_vec();
|
||||
let msg = from_utf8(&payload).expect("should be valid message");
|
||||
println!("::::::::::::::::::::::::::::::::::::::::::::::::::::");
|
||||
println!("Message Received in NODE 1: {}", msg);
|
||||
println!("::::::::::::::::::::::::::::::::::::::::::::::::::::");
|
||||
}
|
||||
WakuEvent::RelayTopicHealthChange(_evt) => {
|
||||
// dbg!("Relay topic change evt", evt);
|
||||
}
|
||||
WakuEvent::ConnectionChange(_evt) => {
|
||||
// dbg!("Conn change evt", evt);
|
||||
}
|
||||
WakuEvent::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err),
|
||||
_ => panic!("event case not expected"),
|
||||
};
|
||||
}
|
||||
})
|
||||
.expect("set event call back working");
|
||||
|
||||
let node1 = node1.start().await.expect("node1 should start");
|
||||
let node2 = node2.start().await.expect("node2 should start");
|
||||
node1.start_node_async().await.expect("node1 should start");
|
||||
node2.start_node_async().await.expect("node2 should start");
|
||||
|
||||
// ========================================================================
|
||||
// Subscribe to pubsub topic
|
||||
let topic = PubsubTopic::new("test");
|
||||
|
||||
node1
|
||||
.relay_subscribe(&topic)
|
||||
.waku_relay_subscribe_async(TOPIC.to_string())
|
||||
.await
|
||||
.expect("node1 should subscribe");
|
||||
|
||||
node2
|
||||
.relay_subscribe(&topic)
|
||||
.waku_relay_subscribe_async(TOPIC.to_string())
|
||||
.await
|
||||
.expect("node2 should subscribe");
|
||||
|
||||
@@ -103,12 +62,16 @@ async fn main() -> Result<(), Error> {
|
||||
// Connect nodes with each other
|
||||
|
||||
let addresses2 = node2
|
||||
.listen_addresses()
|
||||
.waku_listen_addresses_async()
|
||||
.await
|
||||
.expect("should obtain the addresses");
|
||||
let address2 = addresses2
|
||||
.split(',')
|
||||
.next()
|
||||
.expect("node2 should report a listen address");
|
||||
|
||||
node1
|
||||
.connect(&addresses2[0], None)
|
||||
.waku_connect_async(address2.to_string(), 10_000)
|
||||
.await
|
||||
.expect("node1 should connect to node2");
|
||||
|
||||
@@ -122,8 +85,9 @@ async fn main() -> Result<(), Error> {
|
||||
|
||||
let content_topic = WakuContentTopic::new("waku", "2", "test", Encoding::Proto);
|
||||
let message = WakuMessage::new("Hello world", content_topic, 0, Vec::new(), false);
|
||||
let message = serde_json::to_string(&message).expect("message should serialise");
|
||||
node1
|
||||
.relay_publish_message(&message, &topic, None)
|
||||
.waku_relay_publish_async(TOPIC.to_string(), message, 10_000)
|
||||
.await
|
||||
.expect("should have sent the message");
|
||||
|
||||
@@ -135,13 +99,10 @@ async fn main() -> Result<(), Error> {
|
||||
// ========================================================================
|
||||
// Stop both instances
|
||||
|
||||
let node1 = node1.stop().await.expect("should stop");
|
||||
let node2 = node2.stop().await.expect("should stop");
|
||||
node1.stop_node_async().await.expect("should stop");
|
||||
node2.stop_node_async().await.expect("should stop");
|
||||
|
||||
// ========================================================================
|
||||
// Free resources
|
||||
node1.waku_destroy().await.expect("should deallocate");
|
||||
node2.waku_destroy().await.expect("should deallocate");
|
||||
// Resources are freed by LogosDeliveryCtx's Drop impl.
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user