pub mod bindings;
pub mod cli;
pub mod clocks;
pub mod filesystem;
pub mod random;
pub mod sockets;
use crate::WasiView;
use crate::p3::bindings::LinkOptions;
use core::pin::Pin;
use core::task::{Context, Poll};
use tokio::sync::oneshot;
use wasmtime::StoreContextMut;
use wasmtime::component::{Destination, Linker, StreamProducer, StreamResult, VecBuffer};
const DEFAULT_BUFFER_CAPACITY: usize = 8192;
struct FallibleIteratorProducer<I, E> {
iter: I,
result: Option<oneshot::Sender<Result<(), E>>>,
}
impl<I, T, E, D> StreamProducer<D> for FallibleIteratorProducer<I, E>
where
I: Iterator<Item = Result<T, E>> + Send + Unpin + 'static,
T: Send + Sync + 'static,
E: Send + 'static,
{
type Item = T;
type Buffer = VecBuffer<T>;
fn poll_produce<'a>(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
mut store: StoreContextMut<'a, D>,
mut dst: Destination<'a, Self::Item, Self::Buffer>,
_finish: bool,
) -> Poll<wasmtime::Result<StreamResult>> {
let count = dst.remaining(&mut store).unwrap_or(32);
if count == 0 {
return Poll::Ready(Ok(StreamResult::Completed));
}
let mut buf = Vec::new();
let result = loop {
match self.iter.next() {
Some(Ok(item)) => buf.push(item),
Some(Err(e)) => {
self.close(Err(e));
break StreamResult::Dropped;
}
None => {
self.close(Ok(()));
break StreamResult::Dropped;
}
}
if buf.len() >= count {
break StreamResult::Completed;
}
};
dst.set_buffer(buf.into());
return Poll::Ready(Ok(result));
}
}
impl<I, E> FallibleIteratorProducer<I, E> {
fn new(iter: I, result: oneshot::Sender<Result<(), E>>) -> Self {
Self {
iter,
result: Some(result),
}
}
fn close(&mut self, result: Result<(), E>) {
let _ = self.result.take().unwrap().send(result);
}
}
impl<I, E> Drop for FallibleIteratorProducer<I, E> {
fn drop(&mut self) {
if self.result.is_some() {
self.close(Ok(()));
}
}
}
pub fn add_to_linker<T>(linker: &mut Linker<T>) -> wasmtime::Result<()>
where
T: WasiView + 'static,
{
let options = LinkOptions::default();
add_to_linker_with_options(linker, &options)
}
pub fn add_to_linker_with_options<T>(
linker: &mut Linker<T>,
options: &LinkOptions,
) -> wasmtime::Result<()>
where
T: WasiView + 'static,
{
cli::add_to_linker_with_options(linker, &options.into())?;
clocks::add_to_linker(linker)?;
filesystem::add_to_linker(linker)?;
random::add_to_linker(linker)?;
sockets::add_to_linker(linker)?;
Ok(())
}