2022-10-09 16:50:40 +02:00
//! Waku [relay](https://rfc.vac.dev/spec/36/#waku-relay) protocol related methods
2022-10-06 15:51:00 +02:00
// std
use std ::ffi ::{ CStr , CString } ;
use std ::time ::Duration ;
// internal
2023-02-20 12:44:55 +01:00
use crate ::general ::{ Encoding , MessageId , Result , WakuContentTopic , WakuMessage , WakuPubSubTopic } ;
2023-02-14 18:30:08 +01:00
use crate ::utils ::decode_and_free_response ;
2022-10-06 15:51:00 +02:00
/// Create a content topic according to [RFC 23](https://rfc.vac.dev/spec/23/)
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_content_topicchar-applicationname-unsigned-int-applicationversion-char-contenttopicname-char-encoding)
pub fn waku_create_content_topic (
application_name : & str ,
application_version : usize ,
content_topic_name : & str ,
encoding : Encoding ,
) -> WakuContentTopic {
2023-02-14 18:30:08 +01:00
let application_name_ptr = CString ::new ( application_name )
. expect ( " Application name should always transform to CString " )
. into_raw ( ) ;
let application_version = application_version
. try_into ( )
. expect ( " Version should fit within an u32 " ) ;
let content_topic_name_ptr = CString ::new ( content_topic_name )
. expect ( " Content topic should always transform to CString " )
. into_raw ( ) ;
let encoding_ptr = CString ::new ( encoding . to_string ( ) )
. expect ( " Encoding should always transform to CString " )
. into_raw ( ) ;
let result_ptr = unsafe {
let res = waku_sys ::waku_content_topic (
application_name_ptr ,
application_version ,
content_topic_name_ptr ,
encoding_ptr ,
) ;
drop ( CString ::from_raw ( application_name_ptr ) ) ;
drop ( CString ::from_raw ( content_topic_name_ptr ) ) ;
drop ( CString ::from_raw ( encoding_ptr ) ) ;
res
} ;
let result = unsafe { CStr ::from_ptr ( result_ptr ) }
. to_str ( )
. expect ( " &str from result should always be extracted " )
. parse ( )
. expect ( " Content topic data should be always parseable " ) ;
unsafe { waku_sys ::waku_utils_free ( result_ptr ) } ;
result
2022-10-06 15:51:00 +02:00
}
/// Create a pubsub topic according to [RFC 23](https://rfc.vac.dev/spec/23/)
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_pubsub_topicchar-name-char-encoding)
pub fn waku_create_pubsub_topic ( topic_name : & str , encoding : Encoding ) -> WakuPubSubTopic {
2023-02-14 18:30:08 +01:00
let topic_name_ptr = CString ::new ( topic_name )
. expect ( " Topic name should always transform to CString " )
. into_raw ( ) ;
let encoding_ptr = CString ::new ( encoding . to_string ( ) )
. expect ( " Encoding should always transform to CString " )
. into_raw ( ) ;
let result_ptr = unsafe {
let res = waku_sys ::waku_pubsub_topic ( topic_name_ptr , encoding_ptr ) ;
drop ( CString ::from_raw ( topic_name_ptr ) ) ;
drop ( CString ::from_raw ( encoding_ptr ) ) ;
res
} ;
2023-02-20 12:44:55 +01:00
let result = unsafe { CStr ::from_ptr ( result_ptr ) }
2023-02-14 18:30:08 +01:00
. to_str ( )
. expect ( " &str from result should always be extracted " )
. parse ( )
. expect ( " Pubsub topic data should be always parseable " ) ;
unsafe { waku_sys ::waku_utils_free ( result_ptr ) } ;
result
2022-10-06 15:51:00 +02:00
}
/// Default pubsub topic used for exchanging waku messages defined in [RFC 10](https://rfc.vac.dev/spec/10/)
2023-09-27 19:19:59 -04:00
pub fn waku_default_pubsub_topic ( ) -> WakuPubSubTopic {
2023-02-14 18:30:08 +01:00
let result_ptr = unsafe { waku_sys ::waku_default_pubsub_topic ( ) } ;
2023-02-20 12:44:55 +01:00
let result = unsafe { CStr ::from_ptr ( result_ptr ) }
2022-10-06 15:51:00 +02:00
. to_str ( )
. expect ( " &str from result should always be extracted " )
. parse ( )
2023-02-14 18:30:08 +01:00
. expect ( " Default pubsub topic should always be parseable " ) ;
unsafe { waku_sys ::waku_utils_free ( result_ptr ) } ;
result
2022-10-06 15:51:00 +02:00
}
2023-05-10 10:13:50 -04:00
/// Get the list of subscribed pubsub topics in Waku Relay.
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_relay_topics)
pub fn waku_relay_topics ( ) -> Result < Vec < String > > {
let result_ptr = unsafe { waku_sys ::waku_relay_topics ( ) } ;
decode_and_free_response ( result_ptr )
}
2022-10-06 15:51:00 +02:00
/// Publish a message using Waku Relay
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_relay_publishchar-messagejson-char-pubsubtopic-int-timeoutms)
pub fn waku_relay_publish_message (
message : & WakuMessage ,
pubsub_topic : Option < WakuPubSubTopic > ,
2022-10-17 19:30:07 +02:00
timeout : Option < Duration > ,
2022-10-06 15:51:00 +02:00
) -> Result < MessageId > {
let pubsub_topic = pubsub_topic
2023-09-27 19:19:59 -04:00
. unwrap_or_else ( waku_default_pubsub_topic )
2022-10-06 15:51:00 +02:00
. to_string ( ) ;
2023-02-14 18:30:08 +01:00
let message_ptr = CString ::new (
serde_json ::to_string ( & message )
. expect ( " WakuMessages should always be able to success serializing " ) ,
)
. expect ( " CString should build properly from the serialized waku message " )
. into_raw ( ) ;
let pubsub_topic_ptr = CString ::new ( pubsub_topic )
. expect ( " CString should build properly from pubsub topic " )
. into_raw ( ) ;
let result_ptr = unsafe {
let res = waku_sys ::waku_relay_publish (
message_ptr ,
pubsub_topic_ptr ,
2022-10-06 15:51:00 +02:00
timeout
2022-10-17 19:30:07 +02:00
. map ( | duration | {
duration
. as_millis ( )
. try_into ( )
. expect ( " Duration as milliseconds should fit in a i32 " )
} )
. unwrap_or ( 0 ) ,
2023-02-14 18:30:08 +01:00
) ;
drop ( CString ::from_raw ( message_ptr ) ) ;
drop ( CString ::from_raw ( pubsub_topic_ptr ) ) ;
res
} ;
decode_and_free_response ( result_ptr )
2022-10-06 15:51:00 +02:00
}
pub fn waku_enough_peers ( pubsub_topic : Option < WakuPubSubTopic > ) -> Result < bool > {
let pubsub_topic = pubsub_topic
2023-09-27 19:19:59 -04:00
. unwrap_or_else ( waku_default_pubsub_topic )
2022-10-06 15:51:00 +02:00
. to_string ( ) ;
2023-02-14 18:30:08 +01:00
let pubsub_topic_ptr = CString ::new ( pubsub_topic )
. expect ( " CString should build properly from pubsub topic " )
. into_raw ( ) ;
let result_ptr = unsafe {
let res = waku_sys ::waku_relay_enough_peers ( pubsub_topic_ptr ) ;
drop ( CString ::from_raw ( pubsub_topic_ptr ) ) ;
res
} ;
2023-02-20 12:44:55 +01:00
decode_and_free_response ( result_ptr )
2022-10-06 15:51:00 +02:00
}
pub fn waku_relay_subscribe ( pubsub_topic : Option < WakuPubSubTopic > ) -> Result < ( ) > {
let pubsub_topic = pubsub_topic
2023-09-27 19:19:59 -04:00
. unwrap_or_else ( waku_default_pubsub_topic )
2022-10-06 15:51:00 +02:00
. to_string ( ) ;
2023-02-14 18:30:08 +01:00
let pubsub_topic_ptr = CString ::new ( pubsub_topic )
. expect ( " CString should build properly from pubsub topic " )
. into_raw ( ) ;
let result_ptr = unsafe {
let res = waku_sys ::waku_relay_subscribe ( pubsub_topic_ptr ) ;
drop ( CString ::from_raw ( pubsub_topic_ptr ) ) ;
res
} ;
decode_and_free_response ::< bool > ( result_ptr ) . map ( | _ | ( ) )
2022-10-06 15:51:00 +02:00
}
pub fn waku_relay_unsubscribe ( pubsub_topic : Option < WakuPubSubTopic > ) -> Result < ( ) > {
let pubsub_topic = pubsub_topic
2023-09-27 19:19:59 -04:00
. unwrap_or_else ( waku_default_pubsub_topic )
2022-10-06 15:51:00 +02:00
. to_string ( ) ;
2023-02-14 18:30:08 +01:00
let pubsub_topic_ptr = CString ::new ( pubsub_topic )
. expect ( " CString should build properly from pubsub topic " )
. into_raw ( ) ;
let result_ptr = unsafe {
let res = waku_sys ::waku_relay_unsubscribe ( pubsub_topic_ptr ) ;
drop ( CString ::from_raw ( pubsub_topic_ptr ) ) ;
res
} ;
decode_and_free_response ::< bool > ( result_ptr ) . map ( | _ | ( ) )
2022-10-06 15:51:00 +02:00
}