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