Change how replies are emitted

All events that are emitted inside a handler function are seen
as replies to the event that called the handler.
The FromPayloadBytes and ToPayloadBytes traits have been renamed
to FromPayload and IntoPayload. The IntoPayload trait passes the
context in its arguments to allow serializable structures to be
serialized by the default serializer.

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/27/head
trivernis 2 years ago
parent f2606b4704
commit 324a788031
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

2
Cargo.lock generated

@ -93,7 +93,7 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bromine" name = "bromine"
version = "0.15.1" version = "0.16.0"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bincode", "bincode",

@ -1,6 +1,6 @@
[package] [package]
name = "bromine" name = "bromine"
version = "0.15.1" version = "0.16.0"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
readme = "README.md" readme = "README.md"

@ -84,11 +84,13 @@ If no namespace for the event namespace is registered or no handler is registere
the event name, the event will be ignored. the event name, the event will be ignored.
### Receiving answers to emitted events ### Receiving replies to emitted events
When emitting an event to a peer, the emitter can wait for an answer to that event. When emitting an event to a peer, the emitter can wait for an answer to that event.
This is achieved by emitting events as a response to a specific event id. This is achieved by emitting events as a response to a specific event id.
When an event with a reference event id (ref_id) is received, first the registry is When an event with a reference event id (ref_id) is received, first the registry is
searched for handlers waiting for a response (by trying to receive from a channel). searched for handlers waiting for a response (by trying to receive from a channel).
If a handler can be found, the event is passed to the handler waiting for the response. If a handler can be found, the event is passed to the handler waiting for the response.
Otherwise, the event will be processed as a regular event. Otherwise, the event will be processed as a regular event.
Events passed from an event handler are always passed as replies to the event that
called that handler.

@ -1,5 +1,6 @@
use crate::context::Context;
use crate::error::Result; use crate::error::Result;
use crate::payload::{EventReceivePayload, EventSendPayload}; use crate::payload::{FromPayload, IntoPayload};
use crate::prelude::{IPCError, IPCResult}; use crate::prelude::{IPCError, IPCResult};
use byteorder::{BigEndian, ReadBytesExt}; use byteorder::{BigEndian, ReadBytesExt};
use std::error::Error; use std::error::Error;
@ -26,8 +27,8 @@ impl Display for ErrorEventData {
} }
} }
impl EventSendPayload for ErrorEventData { impl IntoPayload for ErrorEventData {
fn to_payload_bytes(self) -> IPCResult<Vec<u8>> { fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
let mut buf = Vec::new(); let mut buf = Vec::new();
buf.append(&mut self.code.to_be_bytes().to_vec()); buf.append(&mut self.code.to_be_bytes().to_vec());
let message_len = self.message.len() as u32; let message_len = self.message.len() as u32;
@ -38,8 +39,8 @@ impl EventSendPayload for ErrorEventData {
} }
} }
impl EventReceivePayload for ErrorEventData { impl FromPayload for ErrorEventData {
fn from_payload_bytes<R: Read>(mut reader: R) -> Result<Self> { fn from_payload<R: Read>(mut reader: R) -> Result<Self> {
let code = reader.read_u16::<BigEndian>()?; let code = reader.read_u16::<BigEndian>()?;
let message_len = reader.read_u32::<BigEndian>()?; let message_len = reader.read_u32::<BigEndian>()?;
let mut message_buf = vec![0u8; message_len as usize]; let mut message_buf = vec![0u8; message_len as usize];

@ -1,6 +1,6 @@
use crate::error::{Error, Result}; use crate::error::{Error, Result};
use crate::events::generate_event_id; use crate::events::generate_event_id;
use crate::events::payload::EventReceivePayload; use crate::events::payload::FromPayload;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use crate::payload::SerdePayload; use crate::payload::SerdePayload;
use crate::prelude::{IPCError, IPCResult}; use crate::prelude::{IPCError, IPCResult};
@ -73,8 +73,8 @@ impl Event {
/// Decodes the payload to the given type implementing the receive payload trait /// Decodes the payload to the given type implementing the receive payload trait
#[tracing::instrument(level = "trace", skip(self))] #[tracing::instrument(level = "trace", skip(self))]
pub fn payload<T: EventReceivePayload>(&self) -> Result<T> { pub fn payload<T: FromPayload>(&self) -> Result<T> {
let payload = T::from_payload_bytes(&self.data[..])?; let payload = T::from_payload(&self.data[..])?;
Ok(payload) Ok(payload)
} }
@ -83,7 +83,7 @@ impl Event {
/// Decodes the payload to the given type implementing DeserializeOwned /// Decodes the payload to the given type implementing DeserializeOwned
#[tracing::instrument(level = "trace", skip(self))] #[tracing::instrument(level = "trace", skip(self))]
pub fn serde_payload<T: DeserializeOwned>(&self) -> Result<T> { pub fn serde_payload<T: DeserializeOwned>(&self) -> Result<T> {
let payload = SerdePayload::<T>::from_payload_bytes(&self.data[..])?; let payload = SerdePayload::<T>::from_payload(&self.data[..])?;
Ok(payload.data()) Ok(payload.data())
} }

@ -5,16 +5,26 @@ use std::io::Read;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
pub use super::payload_serializer::*; pub use super::payload_serializer::*;
/// Trait that serializes a type into bytes and can fail
pub trait TryIntoBytes {
fn try_into_bytes(self) -> IPCResult<Vec<u8>>;
}
/// Trait that serializes a type into bytes and never fails
pub trait IntoBytes {
fn into_bytes(self) -> Vec<u8>;
}
/// Trait to convert event data into sending bytes /// Trait to convert event data into sending bytes
/// It is implemented for all types that implement Serialize /// It is implemented for all types that implement Serialize
pub trait EventSendPayload { pub trait IntoPayload {
fn to_payload_bytes(self) -> IPCResult<Vec<u8>>; fn into_payload(self, ctx: &Context) -> IPCResult<Vec<u8>>;
} }
/// Trait to get the event data from receiving bytes. /// Trait to get the event data from receiving bytes.
/// It is implemented for all types that are DeserializeOwned /// It is implemented for all types that are DeserializeOwned
pub trait EventReceivePayload: Sized { pub trait FromPayload: Sized {
fn from_payload_bytes<R: Read>(reader: R) -> IPCResult<Self>; fn from_payload<R: Read>(reader: R) -> IPCResult<Self>;
} }
/// A payload wrapper type for sending bytes directly without /// A payload wrapper type for sending bytes directly without
@ -35,14 +45,14 @@ impl BytePayload {
} }
} }
impl EventSendPayload for BytePayload { impl IntoPayload for BytePayload {
fn to_payload_bytes(self) -> IPCResult<Vec<u8>> { fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
Ok(self.bytes) Ok(self.bytes)
} }
} }
impl EventReceivePayload for BytePayload { impl FromPayload for BytePayload {
fn from_payload_bytes<R: Read>(mut reader: R) -> IPCResult<Self> { fn from_payload<R: Read>(mut reader: R) -> IPCResult<Self> {
let mut buf = Vec::new(); let mut buf = Vec::new();
reader.read_to_end(&mut buf)?; reader.read_to_end(&mut buf)?;
@ -70,14 +80,10 @@ impl<P1, P2> TandemPayload<P1, P2> {
} }
} }
impl<P1, P2> EventSendPayload for TandemPayload<P1, P2> impl<P1: IntoPayload, P2: IntoPayload> IntoPayload for TandemPayload<P1, P2> {
where fn into_payload(self, ctx: &Context) -> IPCResult<Vec<u8>> {
P1: EventSendPayload, let mut p1_bytes = self.load1.into_payload(&ctx)?;
P2: EventSendPayload, let mut p2_bytes = self.load2.into_payload(&ctx)?;
{
fn to_payload_bytes(self) -> IPCResult<Vec<u8>> {
let mut p1_bytes = self.load1.to_payload_bytes()?;
let mut p2_bytes = self.load2.to_payload_bytes()?;
let mut p1_length_bytes = (p1_bytes.len() as u64).to_be_bytes().to_vec(); let mut p1_length_bytes = (p1_bytes.len() as u64).to_be_bytes().to_vec();
let mut p2_length_bytes = (p2_bytes.len() as u64).to_be_bytes().to_vec(); let mut p2_length_bytes = (p2_bytes.len() as u64).to_be_bytes().to_vec();
@ -92,12 +98,8 @@ where
} }
} }
impl<P1, P2> EventReceivePayload for TandemPayload<P1, P2> impl<P1: FromPayload, P2: FromPayload> FromPayload for TandemPayload<P1, P2> {
where fn from_payload<R: Read>(mut reader: R) -> IPCResult<Self> {
P1: EventReceivePayload,
P2: EventReceivePayload,
{
fn from_payload_bytes<R: Read>(mut reader: R) -> IPCResult<Self> {
let p1_length = reader.read_u64::<BigEndian>()?; let p1_length = reader.read_u64::<BigEndian>()?;
let mut load1_bytes = vec![0u8; p1_length as usize]; let mut load1_bytes = vec![0u8; p1_length as usize];
reader.read_exact(&mut load1_bytes)?; reader.read_exact(&mut load1_bytes)?;
@ -107,14 +109,15 @@ where
reader.read_exact(&mut load2_bytes)?; reader.read_exact(&mut load2_bytes)?;
Ok(Self { Ok(Self {
load1: P1::from_payload_bytes(load1_bytes.as_slice())?, load1: P1::from_payload(load1_bytes.as_slice())?,
load2: P2::from_payload_bytes(load2_bytes.as_slice())?, load2: P2::from_payload(load2_bytes.as_slice())?,
}) })
} }
} }
impl EventSendPayload for () { #[cfg(not(feature = "serialize"))]
fn to_payload_bytes(self) -> IPCResult<Vec<u8>> { impl IntoPayload for () {
fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
Ok(vec![]) Ok(vec![])
} }
} }
@ -123,8 +126,8 @@ impl EventSendPayload for () {
mod serde_payload { mod serde_payload {
use super::DynamicSerializer; use super::DynamicSerializer;
use crate::context::Context; use crate::context::Context;
use crate::payload::EventReceivePayload; use crate::payload::{FromPayload, TryIntoBytes};
use crate::prelude::{EventSendPayload, IPCResult}; use crate::prelude::{IPCResult, IntoPayload};
use byteorder::ReadBytesExt; use byteorder::ReadBytesExt;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::Serialize; use serde::Serialize;
@ -147,10 +150,7 @@ mod serde_payload {
} }
} }
impl<T> Clone for SerdePayload<T> impl<T: Clone> Clone for SerdePayload<T> {
where
T: Clone,
{
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
serializer: self.serializer.clone(), serializer: self.serializer.clone(),
@ -159,11 +159,8 @@ mod serde_payload {
} }
} }
impl<T> EventSendPayload for SerdePayload<T> impl<T: Serialize> TryIntoBytes for SerdePayload<T> {
where fn try_into_bytes(self) -> IPCResult<Vec<u8>> {
T: Serialize,
{
fn to_payload_bytes(self) -> IPCResult<Vec<u8>> {
let mut buf = Vec::new(); let mut buf = Vec::new();
let mut data_bytes = self.serializer.serialize(self.data)?; let mut data_bytes = self.serializer.serialize(self.data)?;
let format_id = self.serializer as u8; let format_id = self.serializer as u8;
@ -174,11 +171,14 @@ mod serde_payload {
} }
} }
impl<T> EventReceivePayload for SerdePayload<T> impl<T: Serialize> IntoPayload for SerdePayload<T> {
where fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
T: DeserializeOwned, self.try_into_bytes()
{ }
fn from_payload_bytes<R: Read>(mut reader: R) -> IPCResult<Self> { }
impl<T: DeserializeOwned> FromPayload for SerdePayload<T> {
fn from_payload<R: Read>(mut reader: R) -> IPCResult<Self> {
let format_id = reader.read_u8()?; let format_id = reader.read_u8()?;
let serializer = DynamicSerializer::from_primitive(format_id as usize)?; let serializer = DynamicSerializer::from_primitive(format_id as usize)?;
let data = serializer.deserialize(reader)?; let data = serializer.deserialize(reader)?;
@ -187,14 +187,13 @@ mod serde_payload {
} }
} }
pub trait IntoSerdePayload: Sized { impl<T: Serialize> IntoPayload for T {
fn into_serde_payload(self, ctx: &Context) -> SerdePayload<Self> { fn into_payload(self, ctx: &Context) -> IPCResult<Vec<u8>> {
ctx.create_serde_payload(self) ctx.create_serde_payload(self).into_payload(&ctx)
} }
} }
impl<T> IntoSerdePayload for T where T: Serialize {}
} }
use crate::context::Context;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
pub use serde_payload::*; pub use serde_payload::*;

@ -1,6 +1,6 @@
use crate::error::{Error, Result}; use crate::error::{Error, Result};
use crate::event::Event; use crate::event::Event;
use crate::ipc::stream_emitter::StreamEmitter; use crate::ipc::stream_emitter::{EmitMetadata, StreamEmitter};
use futures::future; use futures::future;
use futures::future::Either; use futures::future::Either;
use std::collections::HashMap; use std::collections::HashMap;
@ -13,6 +13,7 @@ use tokio::sync::{oneshot, Mutex, RwLock};
use tokio::time::Duration; use tokio::time::Duration;
use typemap_rev::TypeMap; use typemap_rev::TypeMap;
use crate::payload::IntoPayload;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use crate::payload::{DynamicSerializer, SerdePayload}; use crate::payload::{DynamicSerializer, SerdePayload};
@ -26,14 +27,14 @@ pub(crate) type ReplyListeners = Arc<Mutex<HashMap<u64, oneshot::Sender<Event>>>
/// async fn my_callback(ctx: &Context, _event: Event) -> IPCResult<()> { /// async fn my_callback(ctx: &Context, _event: Event) -> IPCResult<()> {
/// // use the emitter on the context object to emit events /// // use the emitter on the context object to emit events
/// // inside callbacks /// // inside callbacks
/// ctx.emitter.emit("ping", ()).await?; /// ctx.emit("ping", ()).await?;
/// Ok(()) /// Ok(())
/// } /// }
/// ``` /// ```
#[derive(Clone)] #[derive(Clone)]
pub struct Context { pub struct Context {
/// The event emitter /// The event emitter
pub emitter: StreamEmitter, emitter: StreamEmitter,
/// Field to store additional context data /// Field to store additional context data
pub data: Arc<RwLock<TypeMap>>, pub data: Arc<RwLock<TypeMap>>,
@ -44,8 +45,10 @@ pub struct Context {
reply_timeout: Duration, reply_timeout: Duration,
ref_id: Option<u64>,
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
default_serializer: DynamicSerializer, pub default_serializer: DynamicSerializer,
} }
impl Context { impl Context {
@ -65,6 +68,42 @@ impl Context {
reply_timeout, reply_timeout,
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
default_serializer, default_serializer,
ref_id: None,
}
}
/// Emits an event with a given payload that can be serialized into bytes
pub async fn emit<S: AsRef<str>, P: IntoPayload>(
&self,
name: S,
payload: P,
) -> Result<EmitMetadata> {
let payload_bytes = payload.into_payload(&self)?;
if let Some(ref_id) = &self.ref_id {
self.emitter
.emit_response(*ref_id, name, payload_bytes)
.await
} else {
self.emitter.emit(name, payload_bytes).await
}
}
/// Emits an event to a specific namespace
pub async fn emit_to<S1: AsRef<str>, S2: AsRef<str>, P: IntoPayload>(
&self,
namespace: S1,
name: S2,
payload: P,
) -> Result<EmitMetadata> {
let payload_bytes = payload.into_payload(&self)?;
if let Some(ref_id) = &self.ref_id {
self.emitter
.emit_response_to(*ref_id, namespace, name, payload_bytes)
.await
} else {
self.emitter.emit_to(namespace, name, payload_bytes).await
} }
} }
@ -115,6 +154,10 @@ impl Context {
let mut listeners = self.reply_listeners.lock().await; let mut listeners = self.reply_listeners.lock().await;
listeners.remove(&ref_id) listeners.remove(&ref_id)
} }
pub(crate) fn set_ref_id(&mut self, id: Option<u64>) {
self.ref_id = id;
}
} }
pub struct PooledContext { pub struct PooledContext {

@ -52,15 +52,14 @@ async fn handle_connection<S: 'static + AsyncProtocolStream>(
} }
/// Handles a single event in a different tokio context /// Handles a single event in a different tokio context
fn handle_event(ctx: Context, handler: Arc<EventHandler>, event: Event) { fn handle_event(mut ctx: Context, handler: Arc<EventHandler>, event: Event) {
ctx.set_ref_id(Some(event.id()));
tokio::spawn(async move { tokio::spawn(async move {
let id = event.id();
if let Err(e) = handler.handle_event(&ctx, event).await { if let Err(e) = handler.handle_event(&ctx, event).await {
// emit an error event // emit an error event
if let Err(e) = ctx if let Err(e) = ctx
.emitter .emit(
.emit_response(
id,
ERROR_EVENT_NAME, ERROR_EVENT_NAME,
ErrorEventData { ErrorEventData {
message: format!("{:?}", e), message: format!("{:?}", e),

@ -1,7 +1,6 @@
use crate::error::Result; use crate::error::Result;
use crate::error_event::{ErrorEventData, ERROR_EVENT_NAME}; use crate::error_event::{ErrorEventData, ERROR_EVENT_NAME};
use crate::events::event::Event; use crate::events::event::Event;
use crate::events::payload::EventSendPayload;
use crate::ipc::context::Context; use crate::ipc::context::Context;
use crate::protocol::AsyncProtocolStream; use crate::protocol::AsyncProtocolStream;
use std::ops::DerefMut; use std::ops::DerefMut;
@ -12,18 +11,11 @@ use tokio::sync::Mutex;
/// An abstraction over any type that implements the AsyncProtocolStream trait /// An abstraction over any type that implements the AsyncProtocolStream trait
/// to emit events and share a connection across multiple /// to emit events and share a connection across multiple
/// contexts. /// contexts.
#[derive(Clone)]
pub struct StreamEmitter { pub struct StreamEmitter {
stream: Arc<Mutex<dyn AsyncWrite + Send + Sync + Unpin + 'static>>, stream: Arc<Mutex<dyn AsyncWrite + Send + Sync + Unpin + 'static>>,
} }
impl Clone for StreamEmitter {
fn clone(&self) -> Self {
Self {
stream: Arc::clone(&self.stream),
}
}
}
impl StreamEmitter { impl StreamEmitter {
pub fn new<P: AsyncProtocolStream + 'static>(stream: P::OwnedSplitWriteHalf) -> Self { pub fn new<P: AsyncProtocolStream + 'static>(stream: P::OwnedSplitWriteHalf) -> Self {
Self { Self {
@ -32,7 +24,7 @@ impl StreamEmitter {
} }
#[tracing::instrument(level = "trace", skip(self, data_bytes))] #[tracing::instrument(level = "trace", skip(self, data_bytes))]
pub async fn _emit( async fn _emit(
&self, &self,
namespace: Option<&str>, namespace: Option<&str>,
event: &str, event: &str,
@ -58,59 +50,48 @@ impl StreamEmitter {
} }
/// Emits an event /// Emits an event
pub async fn emit<S: AsRef<str>, T: EventSendPayload>( pub(crate) async fn emit<S: AsRef<str>>(
&self, &self,
event: S, event: S,
payload: T, payload: Vec<u8>,
) -> Result<EmitMetadata> { ) -> Result<EmitMetadata> {
self._emit(None, event.as_ref(), payload.to_payload_bytes()?, None) self._emit(None, event.as_ref(), payload, None).await
.await
} }
/// Emits an event to a specific namespace /// Emits an event to a specific namespace
pub async fn emit_to<S1: AsRef<str>, S2: AsRef<str>, T: EventSendPayload>( pub(crate) async fn emit_to<S1: AsRef<str>, S2: AsRef<str>>(
&self, &self,
namespace: S1, namespace: S1,
event: S2, event: S2,
payload: T, payload: Vec<u8>,
) -> Result<EmitMetadata> { ) -> Result<EmitMetadata> {
self._emit( self._emit(Some(namespace.as_ref()), event.as_ref(), payload, None)
Some(namespace.as_ref()), .await
event.as_ref(),
payload.to_payload_bytes()?,
None,
)
.await
} }
/// Emits a response to an event /// Emits a response to an event
pub async fn emit_response<S: AsRef<str>, T: EventSendPayload>( pub(crate) async fn emit_response<S: AsRef<str>>(
&self, &self,
event_id: u64, event_id: u64,
event: S, event: S,
payload: T, payload: Vec<u8>,
) -> Result<EmitMetadata> { ) -> Result<EmitMetadata> {
self._emit( self._emit(None, event.as_ref(), payload, Some(event_id))
None, .await
event.as_ref(),
payload.to_payload_bytes()?,
Some(event_id),
)
.await
} }
/// Emits a response to an event to a namespace /// Emits a response to an event to a namespace
pub async fn emit_response_to<S1: AsRef<str>, S2: AsRef<str>, T: EventSendPayload>( pub(crate) async fn emit_response_to<S1: AsRef<str>, S2: AsRef<str>>(
&self, &self,
event_id: u64, event_id: u64,
namespace: S1, namespace: S1,
event: S2, event: S2,
payload: T, payload: Vec<u8>,
) -> Result<EmitMetadata> { ) -> Result<EmitMetadata> {
self._emit( self._emit(
Some(namespace.as_ref()), Some(namespace.as_ref()),
event.as_ref(), event.as_ref(),
payload.to_payload_bytes()?, payload,
Some(event_id), Some(event_id),
) )
.await .await

@ -8,7 +8,7 @@
//! /// Callback ping function //! /// Callback ping function
//! async fn handle_ping(ctx: &Context, event: Event) -> IPCResult<()> { //! async fn handle_ping(ctx: &Context, event: Event) -> IPCResult<()> {
//! println!("Received ping event."); //! println!("Received ping event.");
//! ctx.emitter.emit_response(event.id(), "pong", ()).await?; //! ctx.emit("pong", ()).await?;
//! //!
//! Ok(()) //! Ok(())
//! } //! }
@ -45,7 +45,7 @@
//! // register callback inline //! // register callback inline
//! .on("something", callback!(ctx, event, async move { //! .on("something", callback!(ctx, event, async move {
//! println!("I think the server did something"); //! println!("I think the server did something");
//! ctx.emitter.emit_response_to(event.id(), "mainspace-server", "ok", ()).await?; //! ctx.emit_to("mainspace-server", "ok", ()).await?;
//! Ok(()) //! Ok(())
//! })) //! }))
//! .build() //! .build()
@ -53,7 +53,7 @@
//! .build_client().await.unwrap(); //! .build_client().await.unwrap();
//! //!
//! // emit an initial event //! // emit an initial event
//! let response = ctx.emitter.emit("ping", ()).await.unwrap().await_reply(&ctx).await.unwrap(); //! let response = ctx.emit("ping", ()).await.unwrap().await_reply(&ctx).await.unwrap();
//! assert_eq!(response.name(), "pong"); //! assert_eq!(response.name(), "pong");
//! } //! }
//! ``` //! ```
@ -79,7 +79,7 @@
//! // register callback //! // register callback
//! .on("ping", callback!(ctx, event, async move { //! .on("ping", callback!(ctx, event, async move {
//! println!("Received ping event."); //! println!("Received ping event.");
//! ctx.emitter.emit_response(event.id(), "pong", ()).await?; //! ctx.emit("pong", ()).await?;
//! Ok(()) //! Ok(())
//! })) //! }))
//! .namespace("mainspace-server") //! .namespace("mainspace-server")
@ -91,7 +91,7 @@
//! let mut my_key = data.get_mut::<MyKey>().unwrap(); //! let mut my_key = data.get_mut::<MyKey>().unwrap();
//! *my_key += 1; //! *my_key += 1;
//! } //! }
//! ctx.emitter.emit_response_to(event.id(), "mainspace-client", "something", ()).await?; //! ctx.emit_to("mainspace-client", "something", ()).await?;
//! Ok(()) //! Ok(())
//! })) //! }))
//! .build() //! .build()

@ -17,9 +17,7 @@ async fn it_sends_payloads() {
string: String::from("Hello World"), string: String::from("Hello World"),
}; };
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
let payload = payload.into_serde_payload(&ctx); ctx.emit("ping", payload).await.unwrap();
ctx.emitter.emit("ping", payload).await.unwrap();
// wait for the event to be handled // wait for the event to be handled
tokio::time::sleep(Duration::from_millis(10)).await; tokio::time::sleep(Duration::from_millis(10)).await;
@ -39,10 +37,7 @@ async fn it_receives_payloads() {
string: String::from("Hello World"), string: String::from("Hello World"),
}; };
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
let payload = payload.into_serde_payload(&ctx);
let reply = ctx let reply = ctx
.emitter
.emit("ping", payload) .emit("ping", payload)
.await .await
.unwrap() .unwrap()
@ -79,9 +74,7 @@ async fn handle_ping_event(ctx: &Context, event: Event) -> IPCResult<()> {
let payload = get_simple_payload(&event)?; let payload = get_simple_payload(&event)?;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
{ {
ctx.emitter ctx.emit("pong", payload).await?;
.emit_response(event.id(), "pong", payload.into_serde_payload(&ctx))
.await?;
} }
#[cfg(not(feature = "serialize"))] #[cfg(not(feature = "serialize"))]
{ {
@ -125,7 +118,7 @@ mod payload_impl {
#[cfg(not(feature = "serialize"))] #[cfg(not(feature = "serialize"))]
mod payload_impl { mod payload_impl {
use bromine::error::Result; use bromine::error::Result;
use bromine::payload::{EventReceivePayload, EventSendPayload}; use bromine::payload::{FromPayload, IntoPayload};
use bromine::prelude::IPCResult; use bromine::prelude::IPCResult;
use byteorder::{BigEndian, ReadBytesExt}; use byteorder::{BigEndian, ReadBytesExt};
use std::io::Read; use std::io::Read;
@ -135,7 +128,7 @@ mod payload_impl {
pub number: u32, pub number: u32,
} }
impl EventSendPayload for SimplePayload { impl IntoPayload for SimplePayload {
fn to_payload_bytes(self) -> IPCResult<Vec<u8>> { fn to_payload_bytes(self) -> IPCResult<Vec<u8>> {
let mut buf = Vec::new(); let mut buf = Vec::new();
let string_length = self.string.len() as u16; let string_length = self.string.len() as u16;
@ -150,8 +143,8 @@ mod payload_impl {
} }
} }
impl EventReceivePayload for SimplePayload { impl FromPayload for SimplePayload {
fn from_payload_bytes<R: Read>(mut reader: R) -> Result<Self> { fn from_payload<R: Read>(mut reader: R) -> Result<Self> {
let string_length = reader.read_u16::<BigEndian>()?; let string_length = reader.read_u16::<BigEndian>()?;
let mut string_buf = vec![0u8; string_length as usize]; let mut string_buf = vec![0u8; string_length as usize];
reader.read_exact(&mut string_buf)?; reader.read_exact(&mut string_buf)?;

@ -13,7 +13,7 @@ use utils::protocol::*;
async fn it_sends_events() { async fn it_sends_events() {
let port = get_free_port(); let port = get_free_port();
let ctx = get_client_with_server(port).await; let ctx = get_client_with_server(port).await;
ctx.emitter.emit("ping", EmptyPayload).await.unwrap(); ctx.emit("ping", EmptyPayload).await.unwrap();
// allow the event to be processed // allow the event to be processed
tokio::time::sleep(Duration::from_millis(10)).await; tokio::time::sleep(Duration::from_millis(10)).await;
@ -28,14 +28,8 @@ async fn it_sends_events() {
async fn it_sends_namespaced_events() { async fn it_sends_namespaced_events() {
let port = get_free_port(); let port = get_free_port();
let ctx = get_client_with_server(port).await; let ctx = get_client_with_server(port).await;
ctx.emitter ctx.emit_to("test", "ping", EmptyPayload).await.unwrap();
.emit_to("test", "ping", EmptyPayload) ctx.emit_to("test", "pong", EmptyPayload).await.unwrap();
.await
.unwrap();
ctx.emitter
.emit_to("test", "pong", EmptyPayload)
.await
.unwrap();
// allow the event to be processed // allow the event to be processed
tokio::time::sleep(Duration::from_millis(10)).await; tokio::time::sleep(Duration::from_millis(10)).await;
@ -52,7 +46,6 @@ async fn it_receives_responses() {
let port = get_free_port(); let port = get_free_port();
let ctx = get_client_with_server(port).await; let ctx = get_client_with_server(port).await;
let reply = ctx let reply = ctx
.emitter
.emit("ping", EmptyPayload) .emit("ping", EmptyPayload)
.await .await
.unwrap() .unwrap()
@ -72,10 +65,7 @@ async fn it_receives_responses() {
async fn it_handles_errors() { async fn it_handles_errors() {
let port = get_free_port(); let port = get_free_port();
let ctx = get_client_with_server(port).await; let ctx = get_client_with_server(port).await;
ctx.emitter ctx.emit("create_error", EmptyPayload).await.unwrap();
.emit("create_error", EmptyPayload)
.await
.unwrap();
// allow the event to be processed // allow the event to be processed
tokio::time::sleep(Duration::from_millis(10)).await; tokio::time::sleep(Duration::from_millis(10)).await;
let counter = get_counter_from_context(&ctx).await; let counter = get_counter_from_context(&ctx).await;
@ -90,7 +80,6 @@ async fn it_receives_error_responses() {
let port = get_free_port(); let port = get_free_port();
let ctx = get_client_with_server(port).await; let ctx = get_client_with_server(port).await;
let result = ctx let result = ctx
.emitter
.emit("create_error", EmptyPayload) .emit("create_error", EmptyPayload)
.await .await
.unwrap() .unwrap()
@ -124,9 +113,7 @@ fn get_builder(port: u8) -> IPCBuilder<TestProtocolListener> {
async fn handle_ping_event(ctx: &Context, event: Event) -> IPCResult<()> { async fn handle_ping_event(ctx: &Context, event: Event) -> IPCResult<()> {
increment_counter_for_event(ctx, &event).await; increment_counter_for_event(ctx, &event).await;
ctx.emitter ctx.emit("pong", EmptyPayload).await?;
.emit_response(event.id(), "pong", EmptyPayload)
.await?;
Ok(()) Ok(())
} }
@ -151,8 +138,8 @@ async fn handle_error_event(ctx: &Context, event: Event) -> IPCResult<()> {
pub struct EmptyPayload; pub struct EmptyPayload;
impl EventSendPayload for EmptyPayload { impl IntoPayload for EmptyPayload {
fn to_payload_bytes(self) -> IPCResult<Vec<u8>> { fn into_payload(self, _: &Context) -> IPCResult<Vec<u8>> {
Ok(vec![]) Ok(vec![])
} }
} }

@ -27,8 +27,8 @@ fn it_serializes_json() {
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
fn test_serialization(serializer: DynamicSerializer) { fn test_serialization(serializer: DynamicSerializer) {
let test_payload = get_test_payload(serializer); let test_payload = get_test_payload(serializer);
let payload_bytes = test_payload.clone().to_payload_bytes().unwrap(); let payload_bytes = test_payload.clone().try_into_bytes().unwrap();
let payload = TestSerdePayload::from_payload_bytes(&payload_bytes[..]).unwrap(); let payload = TestSerdePayload::from_payload(&payload_bytes[..]).unwrap();
assert_eq!(payload.data(), test_payload.data()) assert_eq!(payload.data(), test_payload.data())
} }

Loading…
Cancel
Save