use serde::{Deserialize, Serialize};
use super::{
Destination, IncomingEvent, IncomingEventProperties, IncomingMessage, IncomingRequest,
IncomingRequestProperties, IncomingResponse, IncomingResponseProperties,
OutgoingEventProperties, OutgoingRequestProperties, OutgoingResponseProperties,
};
use crate::Error;
#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
#[serde(tag = "type")]
pub(crate) enum IncomingEnvelopeProperties {
Event(IncomingEventProperties),
Request(IncomingRequestProperties),
Response(IncomingResponseProperties),
}
#[derive(Debug, Deserialize)]
pub(crate) struct IncomingEnvelope {
payload: String,
properties: IncomingEnvelopeProperties,
}
impl IncomingEnvelope {
pub(crate) fn properties(&self) -> &IncomingEnvelopeProperties {
&self.properties
}
}
pub(crate) fn into_event(envelope: IncomingEnvelope) -> Result<IncomingMessage<String>, Error> {
let payload = envelope.payload;
match envelope.properties {
IncomingEnvelopeProperties::Event(props) => {
Ok(IncomingMessage::Event(IncomingEvent::new(payload, props)))
}
_ => Err(Error::new("error serializing an envelope into event")),
}
}
pub(crate) fn into_request(envelope: IncomingEnvelope) -> Result<IncomingMessage<String>, Error> {
let payload = envelope.payload;
match envelope.properties {
IncomingEnvelopeProperties::Request(props) => Ok(IncomingMessage::Request(
IncomingRequest::new(payload, props),
)),
_ => Err(Error::new("error serializing an envelope into request")),
}
}
pub(crate) fn into_response(envelope: IncomingEnvelope) -> Result<IncomingMessage<String>, Error> {
let payload = envelope.payload;
match envelope.properties {
IncomingEnvelopeProperties::Response(props) => Ok(IncomingMessage::Response(
IncomingResponse::new(payload, props),
)),
_ => Err(Error::new("error serializing an envelope into response")),
}
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")]
#[serde(tag = "type")]
pub enum OutgoingEnvelopeProperties {
Event(OutgoingEventProperties),
Request(OutgoingRequestProperties),
Response(OutgoingResponseProperties),
}
#[derive(Debug, Serialize)]
pub struct OutgoingEnvelope {
payload: String,
pub(crate) properties: OutgoingEnvelopeProperties,
#[serde(skip)]
#[allow(dead_code)]
destination: Destination,
}
impl OutgoingEnvelope {
pub fn new(
payload: &str,
properties: OutgoingEnvelopeProperties,
destination: Destination,
) -> Self {
Self {
payload: payload.to_owned(),
properties,
destination,
}
}
}
pub trait IntoEnvelope {
fn into_envelope(self) -> Result<OutgoingEnvelope, Error>;
}
use super::OutgoingMessage;
impl<T> IntoEnvelope for super::OutgoingEvent<T>
where
T: serde::Serialize,
{
fn into_envelope(self) -> Result<OutgoingEnvelope, Error> {
let payload = serde_json::to_string(&self.payload)
.map_err(|e| Error::new(&format!("error serializing payload of an envelope, {}", e)))?;
let envelope = OutgoingEnvelope::new(
&payload,
OutgoingEnvelopeProperties::Event(self.properties),
self.destination,
);
Ok(envelope)
}
}
impl<T> IntoEnvelope for super::OutgoingRequest<T>
where
T: serde::Serialize,
{
fn into_envelope(self) -> Result<OutgoingEnvelope, Error> {
let payload = serde_json::to_string(&self.payload)
.map_err(|e| Error::new(&format!("error serializing payload of an envelope, {}", e)))?;
let envelope = OutgoingEnvelope::new(
&payload,
OutgoingEnvelopeProperties::Request(self.properties),
self.destination,
);
Ok(envelope)
}
}
impl<T> IntoEnvelope for super::OutgoingResponse<T>
where
T: serde::Serialize,
{
fn into_envelope(self) -> Result<OutgoingEnvelope, Error> {
let payload = serde_json::to_string(&self.payload)
.map_err(|e| Error::new(&format!("error serializing payload of an envelope, {}", e)))?;
let envelope = OutgoingEnvelope::new(
&payload,
OutgoingEnvelopeProperties::Response(self.properties),
self.destination,
);
Ok(envelope)
}
}
impl<T> IntoEnvelope for OutgoingMessage<T>
where
T: serde::Serialize,
{
fn into_envelope(self) -> Result<OutgoingEnvelope, Error> {
match self {
OutgoingMessage::Event(v) => v.into_envelope(),
OutgoingMessage::Response(v) => v.into_envelope(),
OutgoingMessage::Request(v) => v.into_envelope(),
}
}
}