use crate::codec::{Codec, CodecName};
use crate::logging::TraceContext;
use crate::neuron::Neuron;
use std::sync::Arc;
use uuid::Uuid;
#[derive(Debug)]
pub struct Payload<T, C> {
pub value: Arc<T>,
pub neuron: Arc<dyn Neuron<T, C> + Send + Sync>,
pub trace: TraceContext,
}
impl<T, C> Payload<T, C> {
pub fn from_parts(
value: Arc<T>,
neuron: Arc<dyn Neuron<T, C> + Send + Sync>,
trace: TraceContext,
) -> Self {
Self {
value,
neuron,
trace,
}
}
pub fn with_correlation(
value: T,
neuron: Arc<dyn Neuron<T, C> + Send + Sync>,
correlation_id: Option<Uuid>,
) -> Arc<Self>
where
T: Send + Sync + 'static,
C: Codec<T> + CodecName + Send + Sync + 'static,
{
let correlation = correlation_id.unwrap_or_else(Uuid::now_v7);
let span_id = correlation.as_u128() as u64;
Arc::new(Payload::from_parts(
Arc::new(value),
neuron,
TraceContext::from_parts(correlation, span_id, None),
))
}
pub fn new(value: T, neuron: Arc<dyn Neuron<T, C> + Send + Sync>) -> Arc<Self>
where
T: Send + Sync + 'static,
C: Codec<T> + CodecName + Send + Sync + 'static,
{
Self::with_correlation(value, neuron, None)
}
pub fn builder() -> PayloadBuilder<T, C> {
PayloadBuilder::default()
}
pub fn correlation_id(&self) -> Uuid {
self.trace.correlation_id
}
pub fn span_id(&self) -> u64 {
self.trace.span_id
}
pub fn parent_id(&self) -> Option<u64> {
self.trace.parent_id
}
}
pub struct PayloadBuilder<T, C> {
value: Option<T>,
correlation_id: Option<Uuid>,
neuron: Option<Arc<dyn Neuron<T, C> + Send + Sync>>,
span_id: Option<u64>,
parent_id: Option<u64>,
}
impl<T, C> Default for PayloadBuilder<T, C> {
fn default() -> Self {
Self {
value: None,
correlation_id: None,
neuron: None,
span_id: None,
parent_id: None,
}
}
}
impl<T, C> PayloadBuilder<T, C> {
pub fn value(mut self, value: T) -> Self {
self.value = Some(value);
self
}
pub fn correlation_id(mut self, id: Uuid) -> Self {
self.correlation_id = Some(id);
self
}
pub fn neuron(mut self, neuron: Arc<dyn Neuron<T, C> + Send + Sync>) -> Self {
self.neuron = Some(neuron);
self
}
pub fn span_id(mut self, id: u64) -> Self {
self.span_id = Some(id);
self
}
pub fn parent_id(mut self, id: u64) -> Self {
self.parent_id = Some(id);
self
}
pub fn build(self) -> Result<Arc<Payload<T, C>>, String>
where
T: Send + Sync + 'static,
C: Codec<T> + CodecName + Send + Sync + 'static,
{
let value = self.value.ok_or("Value is required")?;
let neuron = self.neuron.ok_or("Neuron is required")?;
let correlation = self.correlation_id.unwrap_or_else(Uuid::now_v7);
let span = self.span_id.unwrap_or_else(|| correlation.as_u128() as u64);
Ok(Arc::new(Payload {
value: Arc::new(value),
neuron,
trace: TraceContext::from_parts(correlation, span, self.parent_id),
}))
}
}
#[derive(Debug)]
pub struct PayloadRaw<T, C> {
pub value: Arc<Vec<u8>>,
pub neuron: Arc<dyn Neuron<T, C> + Send + Sync>,
pub trace: TraceContext,
}
impl<T, C> PayloadRaw<T, C> {
pub fn from_parts(
value: Arc<Vec<u8>>,
neuron: Arc<dyn Neuron<T, C> + Send + Sync>,
trace: TraceContext,
) -> Self {
Self {
value,
neuron,
trace,
}
}
pub fn with_correlation(
value: Vec<u8>,
neuron: Arc<dyn Neuron<T, C> + Send + Sync>,
correlation_id: Option<Uuid>,
) -> Arc<Self>
where
T: Send + Sync + 'static,
C: Codec<T> + CodecName + Send + Sync + 'static,
{
let correlation = correlation_id.unwrap_or_else(Uuid::now_v7);
let span_id = correlation.as_u128() as u64;
Arc::new(PayloadRaw::from_parts(
Arc::new(value),
neuron,
TraceContext::from_parts(correlation, span_id, None),
))
}
pub fn new(value: Vec<u8>, neuron: Arc<dyn Neuron<T, C> + Send + Sync>) -> Arc<Self>
where
T: Send + Sync + 'static,
C: Codec<T> + CodecName + Send + Sync + 'static,
{
Self::with_correlation(value, neuron, None)
}
pub fn correlation_id(&self) -> Uuid {
self.trace.correlation_id
}
pub fn span_id(&self) -> u64 {
self.trace.span_id
}
pub fn parent_id(&self) -> Option<u64> {
self.trace.parent_id
}
}