* Added topics type aliases

* More general type aliases

* Implement event module

* Added public interface for WakuMessageEvent

* Skip fat pointers in event callback

* Nitpick and docs for set_event_callback
This commit is contained in:
Daniel Sanchez 2022-09-29 15:17:52 +02:00 committed by GitHub
parent 7b7ba2975d
commit ba74c68c60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 6 deletions

72
waku/src/events/mod.rs Normal file
View File

@ -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<F: FnMut(Signal)>(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| {});
}
}

View File

@ -3,6 +3,10 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
// internal // internal
pub type PubsubTopic = String;
pub type ContentTopic = String;
pub type WakuMessageVersion = usize;
/// JsonResponse wrapper. /// JsonResponse wrapper.
/// `go-waku` ffi returns this type as a `char *` as per the [specification](https://rfc.vac.dev/spec/36/#jsonresponse-type) /// `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. /// This is internal, as it is better to use rust plain `Result` type.
@ -33,9 +37,9 @@ impl<T> From<JsonResponse<T>> for Response<T> {
pub struct WakuMessage { pub struct WakuMessage {
payload: Box<[u8]>, payload: Box<[u8]>,
/// The content topic to be set on the message /// The content topic to be set on the message
content_topic: String, content_topic: ContentTopic,
/// The Waku Message version number /// The Waku Message version number
version: usize, version: WakuMessageVersion,
/// Unix timestamp in nanoseconds /// Unix timestamp in nanoseconds
timestamp: usize, timestamp: usize,
} }
@ -58,7 +62,7 @@ pub struct DecodedPayload {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ContentFilter { pub struct ContentFilter {
/// The content topic of a Waku message /// 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 /// 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 /// Array of [`ContentFilter`] being subscribed to / unsubscribed from
content_filters: Vec<ContentFilter>, content_filters: Vec<ContentFilter>,
/// Optional pubsub topic /// Optional pubsub topic
pubsub_topic: Option<String>, pubsub_topic: Option<PubsubTopic>,
} }
/// Criteria used to retrieve historical messages /// Criteria used to retrieve historical messages
@ -77,7 +81,7 @@ pub struct FilterSubscription {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct StoreQuery { pub struct StoreQuery {
/// The pubsub topic on which messages are published /// The pubsub topic on which messages are published
pubsub_topic: Option<String>, pubsub_topic: Option<PubsubTopic>,
/// Array of [`ContentFilter`] to query for historical messages /// Array of [`ContentFilter`] to query for historical messages
content_filters: Vec<ContentFilter>, content_filters: Vec<ContentFilter>,
/// The inclusive lower bound on the timestamp of queried messages. /// 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 /// UNIX timestamp in nanoseconds at which the message is generated by its sender
sender_time: usize, sender_time: usize,
/// The pubsub topic of the message at this [`MessageIndex`] /// The pubsub topic of the message at this [`MessageIndex`]
pubsub_topic: String, pubsub_topic: PubsubTopic,
} }

View File

@ -1,4 +1,5 @@
mod general; mod general;
mod events;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {