pub mod default_impl;
mod producer_impl;
mod request_reply_impl;
mod resource;
mod server;
mod types_impl;
mod generated {
#![allow(missing_docs)]
pub use wasi::messaging::types::Error;
pub use crate::host::resource::{ClientProxy, MessageProxy, RequestOptions};
wasmtime::component::bindgen!({
world: "messaging-request-reply",
path: "wit",
imports: {
default: store | tracing | trappable,
},
exports: {
default: store | tracing | trappable,
},
with: {
"wasi:messaging/request-reply.request-options": RequestOptions,
"wasi:messaging/types.client": ClientProxy,
"wasi:messaging/types.message": MessageProxy,
},
trappable_error_type: {
"wasi:messaging/types.error" => Error,
},
});
}
use std::fmt::Debug;
use std::sync::Arc;
pub use omnia::FutureResult;
use omnia::{Host, Server, State};
use wasmtime::component::{HasData, Linker};
use wasmtime_wasi::{ResourceTable, ResourceTableError};
pub use self::default_impl::MessagingDefault;
pub use self::generated::MessagingRequestReply;
pub use self::generated::wasi::messaging::types::Error;
use self::generated::wasi::messaging::{producer, request_reply, types};
pub use self::resource::*;
pub type Result<T, E = Error> = anyhow::Result<T, E>;
#[derive(Debug)]
pub struct WasiMessaging;
impl HasData for WasiMessaging {
type Data<'a> = WasiMessagingCtxView<'a>;
}
impl<T> Host<T> for WasiMessaging
where
T: WasiMessagingView + 'static,
{
fn add_to_linker(linker: &mut Linker<T>) -> anyhow::Result<()> {
producer::add_to_linker::<_, Self>(linker, T::messaging)?;
request_reply::add_to_linker::<_, Self>(linker, T::messaging)?;
Ok(types::add_to_linker::<_, Self>(linker, T::messaging)?)
}
}
impl<S> Server<S> for WasiMessaging
where
S: State,
S::StoreCtx: WasiMessagingView,
{
async fn run(&self, state: &S) -> anyhow::Result<()> {
server::run(state).await
}
}
pub trait WasiMessagingView: Send {
fn messaging(&mut self) -> WasiMessagingCtxView<'_>;
}
pub struct WasiMessagingCtxView<'a> {
pub ctx: &'a mut dyn WasiMessagingCtx,
pub table: &'a mut ResourceTable,
}
#[allow(unused)]
pub trait WasiMessagingCtx: Debug + Send + Sync + 'static {
fn connect(&self) -> FutureResult<Arc<dyn Client>>;
fn new_message(&self, data: Vec<u8>) -> anyhow::Result<Arc<dyn Message>>;
fn set_content_type(
&self, message: Arc<dyn Message>, content_type: String,
) -> anyhow::Result<Arc<dyn Message>>;
fn set_payload(
&self, message: Arc<dyn Message>, data: Vec<u8>,
) -> anyhow::Result<Arc<dyn Message>>;
fn add_metadata(
&self, message: Arc<dyn Message>, key: String, value: String,
) -> anyhow::Result<Arc<dyn Message>>;
fn set_metadata(
&self, message: Arc<dyn Message>, metadata: Metadata,
) -> anyhow::Result<Arc<dyn Message>>;
fn remove_metadata(
&self, message: Arc<dyn Message>, key: String,
) -> anyhow::Result<Arc<dyn Message>>;
}
impl From<anyhow::Error> for Error {
fn from(err: anyhow::Error) -> Self {
Self::Other(err.to_string())
}
}
impl From<ResourceTableError> for Error {
fn from(err: ResourceTableError) -> Self {
Self::Other(err.to_string())
}
}
impl From<wasmtime::Error> for Error {
fn from(err: wasmtime::Error) -> Self {
Self::Other(err.to_string())
}
}
#[macro_export]
macro_rules! omnia_wasi_view {
($store_ctx:ty, $field_name:ident) => {
impl omnia_wasi_messaging::WasiMessagingView for $store_ctx {
fn messaging(&mut self) -> omnia_wasi_messaging::WasiMessagingCtxView<'_> {
omnia_wasi_messaging::WasiMessagingCtxView {
ctx: &mut self.$field_name,
table: &mut self.table,
}
}
}
};
}