use thiserror::Error;
use super::{FirstFrameHeader, MessageKey};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct EnvelopeId(pub u32);
impl From<u32> for EnvelopeId {
fn from(value: u32) -> Self { Self(value) }
}
impl From<EnvelopeId> for u32 {
fn from(value: EnvelopeId) -> Self { value.0 }
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct CorrelationId(pub u64);
impl From<u64> for CorrelationId {
fn from(value: u64) -> Self { Self(value) }
}
impl From<CorrelationId> for u64 {
fn from(value: CorrelationId) -> Self { value.0 }
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct EnvelopeRouting {
pub envelope_id: EnvelopeId,
pub correlation_id: Option<CorrelationId>,
}
#[derive(Debug)]
pub struct FirstFrameInput<'a> {
pub header: &'a FirstFrameHeader,
pub routing: EnvelopeRouting,
pub metadata: Vec<u8>,
pub body: &'a [u8],
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Error)]
pub enum FirstFrameInputError {
#[error("metadata length mismatch: header declares {header_len} bytes, got {actual_len}")]
MetadataLengthMismatch {
header_len: usize,
actual_len: usize,
},
#[error("body length mismatch: header declares {header_len} bytes, got {actual_len}")]
BodyLengthMismatch {
header_len: usize,
actual_len: usize,
},
}
impl<'a> FirstFrameInput<'a> {
pub fn new(
header: &'a FirstFrameHeader,
routing: EnvelopeRouting,
metadata: Vec<u8>,
body: &'a [u8],
) -> Result<Self, FirstFrameInputError> {
if header.metadata_len != metadata.len() {
return Err(FirstFrameInputError::MetadataLengthMismatch {
header_len: header.metadata_len,
actual_len: metadata.len(),
});
}
if header.body_len != body.len() {
return Err(FirstFrameInputError::BodyLengthMismatch {
header_len: header.body_len,
actual_len: body.len(),
});
}
Ok(Self {
header,
routing,
metadata,
body,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AssembledMessage {
message_key: MessageKey,
routing: EnvelopeRouting,
metadata: Vec<u8>,
body: Vec<u8>,
}
impl AssembledMessage {
#[must_use]
pub fn new(
message_key: MessageKey,
routing: EnvelopeRouting,
metadata: Vec<u8>,
body: Vec<u8>,
) -> Self {
Self {
message_key,
routing,
metadata,
body,
}
}
#[must_use]
pub const fn message_key(&self) -> MessageKey { self.message_key }
#[must_use]
pub const fn routing(&self) -> EnvelopeRouting { self.routing }
#[must_use]
pub fn metadata(&self) -> &[u8] { &self.metadata }
#[must_use]
pub fn body(&self) -> &[u8] { &self.body }
#[must_use]
pub fn into_body(self) -> Vec<u8> { self.body }
}