diff --git a/waku/src/events/mod.rs b/waku/src/events/mod.rs new file mode 100644 index 0000000..1d859d1 --- /dev/null +++ b/waku/src/events/mod.rs @@ -0,0 +1,72 @@ +// std +use std::ffi::{c_char, CStr}; +// crates +use serde::{Deserialize, Serialize}; +// internal +use crate::general::{PubsubTopic, WakuMessage}; + +#[derive(Serialize, Deserialize)] +pub struct Signal { + #[serde(alias = "type")] + _type: String, + event: Event, +} + +#[derive(Serialize, Deserialize)] +#[serde(tag = "untagged", rename_all = "camelCase")] +pub enum Event { + WakuMessage(WakuMessageEvent), +} + +/// Type of `event` field for a `message` event +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct WakuMessageEvent { + /// The pubsub topic on which the message was received + pubsub_topic: PubsubTopic, + /// The message id + message_id: String, + /// The message in [`WakuMessage`] format + waku_message: WakuMessage, +} + +impl WakuMessageEvent { + pub fn pubsub_topic(&self) -> &PubsubTopic { + &self.pubsub_topic + } + + pub fn message_id(&self) -> &String { + &self.message_id + } + + pub fn waku_message(&self) -> &WakuMessage { + &self.waku_message + } +} + +/// Register callback to act as event handler and receive application signals, +/// which are used to react to asynchronous events in Waku +pub fn waku_set_event_callback(mut callback: F) { + let mut callback_wrapper = move |data: *const c_char| { + let raw_response = unsafe { CStr::from_ptr(data) } + .to_str() + .expect("Not null ptr"); + let data: Signal = serde_json::from_str(raw_response).expect("Parsing signal to succeed"); + callback(data); + }; + let mut callback_ptr: &mut dyn FnMut(*const c_char) = &mut callback_wrapper; + unsafe { + waku_sys::waku_set_event_callback(&mut callback_ptr as *mut &mut _ as *mut std::ffi::c_void) + }; +} + +#[cfg(test)] +mod tests { + use crate::events::waku_set_event_callback; + + // TODO: how to actually send a signal and check if the callback is run? + #[test] + fn set_event_callback() { + waku_set_event_callback(|_signal| {}); + } +} diff --git a/waku/src/general/mod.rs b/waku/src/general/mod.rs index 3fbb5cd..edf2a50 100644 --- a/waku/src/general/mod.rs +++ b/waku/src/general/mod.rs @@ -3,6 +3,10 @@ use serde::{Deserialize, Serialize}; // internal +pub type PubsubTopic = String; +pub type ContentTopic = String; +pub type WakuMessageVersion = usize; + /// JsonResponse wrapper. /// `go-waku` ffi returns this type as a `char *` as per the [specification](https://rfc.vac.dev/spec/36/#jsonresponse-type) /// This is internal, as it is better to use rust plain `Result` type. @@ -33,9 +37,9 @@ impl From> for Response { pub struct WakuMessage { payload: Box<[u8]>, /// The content topic to be set on the message - content_topic: String, + content_topic: ContentTopic, /// The Waku Message version number - version: usize, + version: WakuMessageVersion, /// Unix timestamp in nanoseconds timestamp: usize, } @@ -58,7 +62,7 @@ pub struct DecodedPayload { #[serde(rename_all = "camelCase")] pub struct ContentFilter { /// The content topic of a Waku message - content_topic: String, + content_topic: ContentTopic, } /// The criteria to create subscription to a light node in JSON Format @@ -69,7 +73,7 @@ pub struct FilterSubscription { /// Array of [`ContentFilter`] being subscribed to / unsubscribed from content_filters: Vec, /// Optional pubsub topic - pubsub_topic: Option, + pubsub_topic: Option, } /// Criteria used to retrieve historical messages @@ -77,7 +81,7 @@ pub struct FilterSubscription { #[serde(rename_all = "camelCase")] pub struct StoreQuery { /// The pubsub topic on which messages are published - pubsub_topic: Option, + pubsub_topic: Option, /// Array of [`ContentFilter`] to query for historical messages content_filters: Vec, /// The inclusive lower bound on the timestamp of queried messages. @@ -124,5 +128,5 @@ pub struct MessageIndex { /// UNIX timestamp in nanoseconds at which the message is generated by its sender sender_time: usize, /// The pubsub topic of the message at this [`MessageIndex`] - pubsub_topic: String, + pubsub_topic: PubsubTopic, } diff --git a/waku/src/lib.rs b/waku/src/lib.rs index 0d6c116..2c44c9a 100644 --- a/waku/src/lib.rs +++ b/waku/src/lib.rs @@ -1,4 +1,5 @@ mod general; +mod events; #[cfg(test)] mod tests {