use async_trait::async_trait;
#[cfg(feature = "iroh")]
use crate::error::Error;
use crate::error::Result;
use crate::inbox::Inbox;
#[cfg(feature = "iroh")]
use crate::ipfs::DidDocumentResolver;
use crate::service::INBOX_PROTOCOL_ID;
#[cfg(feature = "iroh")]
use crate::transport::resolve_endpoint_for_protocol;
#[cfg(feature = "iroh")]
use crate::Document;
use crate::Message;
#[cfg(feature = "iroh")]
use crate::Outbox;
pub const DEFAULT_INBOX_CAPACITY: usize = 256;
pub const DEFAULT_DELIVERY_PROTOCOL_ID: &str = INBOX_PROTOCOL_ID;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait MaEndpoint: Send + Sync {
fn id(&self) -> String;
fn service(&mut self, protocol: &str) -> Inbox<Message>;
fn services(&self) -> Vec<String>;
fn services_json(&self) -> serde_json::Value {
serde_json::Value::Array(
self.services()
.into_iter()
.map(serde_json::Value::String)
.collect(),
)
}
async fn send_to(&self, target: &str, protocol: &str, message: &Message) -> Result<()>;
#[cfg(feature = "iroh")]
async fn outbox(
&self,
resolver: &dyn DidDocumentResolver,
did: &str,
protocol: &str,
) -> Result<Outbox> {
let doc = resolver.resolve(did).await?;
let services = doc
.ma
.as_ref()
.and_then(|ma| ma.get("services").ok().flatten())
.and_then(|services| serde_json::to_value(services).ok());
let endpoint_id =
resolve_endpoint_for_protocol(services.as_ref(), protocol).ok_or_else(|| {
Error::NoInboxTransport(format!("{did} has no service for {protocol}"))
})?;
self.connect_outbox(&doc, &endpoint_id, did, protocol).await
}
#[cfg(feature = "iroh")]
async fn connect_outbox(
&self,
doc: &Document,
endpoint_id: &str,
did: &str,
protocol: &str,
) -> Result<Outbox>;
async fn send(&self, target: &str, message: &Message) -> Result<()> {
self.send_to(target, DEFAULT_DELIVERY_PROTOCOL_ID, message)
.await
}
}