use crate::error::{Error, Result};
use crate::Message;
use async_trait::async_trait;
#[async_trait]
pub(crate) trait OutboxWire: Send + std::fmt::Debug {
async fn send_payload(&mut self, payload: &[u8]) -> Result<()>;
fn close_box(self: Box<Self>);
}
#[derive(Debug)]
pub struct Outbox {
inner: Option<Box<dyn OutboxWire>>,
did: String,
protocol: String,
}
impl Outbox {
pub(crate) fn from_transport<T>(transport: T, did: String, protocol: String) -> Self
where
T: OutboxWire + 'static,
{
Self {
inner: Some(Box::new(transport)),
did,
protocol,
}
}
pub async fn send(&mut self, message: &Message) -> Result<()> {
message.headers().validate()?;
let cbor = message.encode()?;
match self.inner.as_mut() {
Some(transport) => transport.send_payload(&cbor).await,
None => Err(Error::ConnectionClosed("outbox is closed".to_string())),
}
}
#[must_use]
pub fn did(&self) -> &str {
&self.did
}
#[must_use]
pub fn protocol(&self) -> &str {
&self.protocol
}
pub fn close(mut self) {
if let Some(transport) = self.inner.take() {
transport.close_box();
}
}
}