1 use anyhow::Result; 2 use wasmtime::component::{Accessor, AccessorTask, HostStream, Resource, StreamWriter}; 3 use wasmtime_wasi::p2::IoView; 4 5 use super::Ctx; 6 7 pub mod bindings { 8 wasmtime::component::bindgen!({ 9 trappable_imports: true, 10 path: "wit", 11 world: "read-resource-stream", 12 concurrent_imports: true, 13 concurrent_exports: true, 14 async: true, 15 with: { 16 "local:local/resource-stream/x": super::ResourceStreamX, 17 } 18 }); 19 } 20 21 pub struct ResourceStreamX; 22 23 impl bindings::local::local::resource_stream::HostXConcurrent for Ctx { 24 async fn foo<T>(accessor: &Accessor<T, Self>, x: Resource<ResourceStreamX>) -> Result<()> { 25 accessor.with(|mut view| { 26 _ = view.get().table().get(&x)?; 27 Ok(()) 28 }) 29 } 30 } 31 32 impl bindings::local::local::resource_stream::HostX for Ctx { 33 async fn drop(&mut self, x: Resource<ResourceStreamX>) -> Result<()> { 34 IoView::table(self).delete(x)?; 35 Ok(()) 36 } 37 } 38 39 impl bindings::local::local::resource_stream::HostConcurrent for Ctx { 40 async fn foo<T: 'static>( 41 accessor: &Accessor<T, Self>, 42 count: u32, 43 ) -> wasmtime::Result<HostStream<Resource<ResourceStreamX>>> { 44 struct Task { 45 tx: StreamWriter<Option<Resource<ResourceStreamX>>>, 46 47 count: u32, 48 } 49 50 impl<T> AccessorTask<T, Ctx, Result<()>> for Task { 51 async fn run(self, accessor: &Accessor<T, Ctx>) -> Result<()> { 52 let mut tx = self.tx; 53 for _ in 0..self.count { 54 let item = 55 accessor.with(|mut view| view.get().table().push(ResourceStreamX))?; 56 tx.write_all(accessor, Some(item)).await; 57 } 58 Ok(()) 59 } 60 } 61 62 let (tx, rx) = accessor.with(|mut view| { 63 let instance = view.instance(); 64 instance.stream::<_, _, Option<_>>(&mut view) 65 })?; 66 accessor.spawn(Task { tx, count }); 67 Ok(rx.into()) 68 } 69 } 70 71 impl bindings::local::local::resource_stream::Host for Ctx {} 72