@@ -28,11 +28,11 @@ wasmtime::component::bindgen!({
2828use {
2929 anyhow:: anyhow,
3030 bytes:: BytesMut ,
31- std:: { fmt, future:: Future , mem} ,
31+ std:: { fmt, future:: Future , marker , mem} ,
3232 wasi:: http:: types:: { ErrorCode , HeaderError , Method , RequestOptionsError , Scheme } ,
3333 wasmtime:: component:: {
34- Accessor , AccessorTask , ErrorContext , FutureReader , HostFuture , HostStream , Linker ,
35- Resource , ResourceTable , StreamReader ,
34+ Accessor , AccessorTask , ErrorContext , FutureReader , HasData , HostFuture , HostStream ,
35+ Linker , Resource , ResourceTable , StreamReader ,
3636 } ,
3737} ;
3838
@@ -50,60 +50,60 @@ impl fmt::Display for Scheme {
5050 }
5151}
5252
53- pub trait WasiHttpView : Send + Sized {
54- fn table ( & mut self ) -> & mut ResourceTable ;
53+ pub trait WasiHttpViewConcurrent : Send + ' static {
54+ type View < ' a > : WasiHttpView ;
5555
5656 fn send_request < T : ' static > (
57- accessor : & mut Accessor < T , Self > ,
57+ accessor : & mut Accessor < T , WasiHttp < Self > > ,
5858 request : Resource < Request > ,
5959 ) -> impl Future < Output = wasmtime:: Result < Result < Resource < Response > , ErrorCode > > > + Send + Sync ;
6060}
6161
62- impl < T : WasiHttpView > WasiHttpView for & mut T {
62+ pub trait WasiHttpView : Send {
63+ fn table ( & mut self ) -> & mut ResourceTable ;
64+ }
65+
66+ impl < T : WasiHttpView + ?Sized > WasiHttpView for & mut T {
6367 fn table ( & mut self ) -> & mut ResourceTable {
6468 ( * self ) . table ( )
6569 }
66-
67- fn send_request < U : ' static > (
68- accessor : & mut Accessor < U , Self > ,
69- request : Resource < Request > ,
70- ) -> impl Future < Output = wasmtime:: Result < Result < Resource < Response > , ErrorCode > > > + Send + Sync
71- {
72- accessor. forward ( |v| * v, SendRequestTask { request } )
73- }
7470}
7571
76- struct SendRequestTask {
72+ struct SendRequestTask < C > {
7773 request : Resource < Request > ,
74+ _marker : marker:: PhantomData < fn ( ) -> C > ,
7875}
7976
80- impl < T : ' static , U : WasiHttpView >
81- AccessorTask < T , U , wasmtime:: Result < Result < Resource < Response > , ErrorCode > > >
82- for SendRequestTask
77+ impl < T : ' static , C >
78+ AccessorTask < T , WasiHttp < C > , wasmtime:: Result < Result < Resource < Response > , ErrorCode > > >
79+ for SendRequestTask < C >
80+ where
81+ C : WasiHttpViewConcurrent ,
8382{
8483 async fn run (
8584 self ,
86- accessor : & mut wasmtime:: component:: Accessor < T , U > ,
85+ accessor : & mut wasmtime:: component:: Accessor < T , WasiHttp < C > > ,
8786 ) -> wasmtime:: Result < Result < Resource < Response > , ErrorCode > > {
88- U :: send_request ( accessor, self . request ) . await
87+ C :: send_request ( accessor, self . request ) . await
8988 }
9089}
9190
91+ pub struct WasiHttp < C : ?Sized > ( marker:: PhantomData < C > ) ;
92+
93+ impl < C : ?Sized > HasData for WasiHttp < C >
94+ where
95+ C : WasiHttpViewConcurrent ,
96+ {
97+ type Data < ' a > = WasiHttpImpl < C :: View < ' a > > ;
98+ }
99+
92100#[ repr( transparent) ]
93101pub struct WasiHttpImpl < T > ( pub T ) ;
94102
95103impl < T : WasiHttpView > WasiHttpView for WasiHttpImpl < T > {
96104 fn table ( & mut self ) -> & mut ResourceTable {
97105 self . 0 . table ( )
98106 }
99-
100- fn send_request < U : ' static > (
101- accessor : & mut Accessor < U , Self > ,
102- request : Resource < Request > ,
103- ) -> impl Future < Output = wasmtime:: Result < Result < Resource < Response > , ErrorCode > > > + Send + Sync
104- {
105- accessor. forward ( |v| & mut v. 0 , SendRequestTask { request } )
106- }
107107}
108108
109109pub struct Body {
@@ -216,22 +216,22 @@ impl<T: WasiHttpView> wasi::http::types::HostFields for WasiHttpImpl<T> {
216216 }
217217}
218218
219- impl < T : WasiHttpView > wasi:: http:: types:: HostBody for WasiHttpImpl < T > {
220- async fn new < U > (
221- accessor : & mut Accessor < U , Self > ,
219+ impl < C : WasiHttpViewConcurrent > wasi:: http:: types:: HostBodyConcurrent for WasiHttp < C > {
220+ async fn new < T > (
221+ accessor : & mut Accessor < T , Self > ,
222222 stream : HostStream < u8 > ,
223223 ) -> wasmtime:: Result < Resource < Body > > {
224224 accessor. with ( |mut view| {
225225 let body = Body {
226226 stream : Some ( stream. into_reader ( & mut view) ) ,
227227 trailers : None ,
228228 } ;
229- Ok ( view. table ( ) . push ( body) ?)
229+ Ok ( view. get ( ) . table ( ) . push ( body) ?)
230230 } )
231231 }
232232
233- async fn new_with_trailers < U > (
234- accessor : & mut Accessor < U , Self > ,
233+ async fn new_with_trailers < T > (
234+ accessor : & mut Accessor < T , Self > ,
235235 stream : HostStream < u8 > ,
236236 trailers : HostFuture < Resource < Fields > > ,
237237 ) -> wasmtime:: Result < Resource < Body > > {
@@ -240,27 +240,18 @@ impl<T: WasiHttpView> wasi::http::types::HostBody for WasiHttpImpl<T> {
240240 stream : Some ( stream. into_reader ( & mut view) ) ,
241241 trailers : Some ( trailers. into_reader ( & mut view) ) ,
242242 } ;
243- Ok ( view. table ( ) . push ( body) ?)
243+ Ok ( view. get ( ) . table ( ) . push ( body) ?)
244244 } )
245245 }
246246
247- fn stream ( & mut self , this : Resource < Body > ) -> wasmtime:: Result < Result < HostStream < u8 > , ( ) > > {
248- // TODO: This should return a child handle
249- let stream = self . table ( ) . get_mut ( & this) ?. stream . take ( ) . ok_or_else ( || {
250- anyhow ! ( "todo: allow wasi:http/types#body.stream to be called multiple times" )
251- } ) ?;
252-
253- Ok ( Ok ( stream. into ( ) ) )
254- }
255-
256247 // TODO: once access to the store is possible in a non-async context (similar to Accessor pattern)
257248 // we should convert this to a sync function that works w/ &mut self.
258- async fn finish < U > (
259- accessor : & mut Accessor < U , Self > ,
249+ async fn finish < T > (
250+ accessor : & mut Accessor < T , Self > ,
260251 this : Resource < Body > ,
261252 ) -> wasmtime:: Result < HostFuture < Resource < Fields > > > {
262253 let trailers = accessor. with ( |mut store| {
263- let trailers = store. table ( ) . delete ( this) ?. trailers ;
254+ let trailers = store. get ( ) . table ( ) . delete ( this) ?. trailers ;
264255 Ok :: < FutureReader < _ > , anyhow:: Error > ( match trailers {
265256 Some ( t) => t,
266257 None => {
@@ -272,6 +263,17 @@ impl<T: WasiHttpView> wasi::http::types::HostBody for WasiHttpImpl<T> {
272263
273264 Ok ( trailers. into ( ) )
274265 }
266+ }
267+
268+ impl < T : WasiHttpView > wasi:: http:: types:: HostBody for WasiHttpImpl < T > {
269+ fn stream ( & mut self , this : Resource < Body > ) -> wasmtime:: Result < Result < HostStream < u8 > , ( ) > > {
270+ // TODO: This should return a child handle
271+ let stream = self . table ( ) . get_mut ( & this) ?. stream . take ( ) . ok_or_else ( || {
272+ anyhow ! ( "todo: allow wasi:http/types#body.stream to be called multiple times" )
273+ } ) ?;
274+
275+ Ok ( Ok ( stream. into ( ) ) )
276+ }
275277
276278 fn drop ( & mut self , this : Resource < Body > ) -> wasmtime:: Result < ( ) > {
277279 self . table ( ) . delete ( this) ?;
@@ -507,31 +509,36 @@ impl<T: WasiHttpView> wasi::http::types::HostRequestOptions for WasiHttpImpl<T>
507509 }
508510}
509511
512+ impl < C : WasiHttpViewConcurrent > wasi:: http:: types:: HostConcurrent for WasiHttp < C > { }
513+
510514impl < T : WasiHttpView > wasi:: http:: types:: Host for WasiHttpImpl < T > {
511515 fn http_error_code ( & mut self , _error : ErrorContext ) -> wasmtime:: Result < Option < ErrorCode > > {
512516 Err ( anyhow ! ( "todo: implement wasi:http/types#http-error-code" ) )
513517 }
514518}
515519
516- impl < T : WasiHttpView > wasi:: http:: handler:: Host for WasiHttpImpl < T > {
517- async fn handle < U : ' static > (
518- accessor : & mut Accessor < U , Self > ,
520+ impl < C : WasiHttpViewConcurrent > wasi:: http:: handler:: HostConcurrent for WasiHttp < C > {
521+ async fn handle < T : ' static > (
522+ accessor : & mut Accessor < T , Self > ,
519523 request : Resource < Request > ,
520524 ) -> wasmtime:: Result < Result < Resource < Response > , ErrorCode > > {
521- accessor
522- . forward ( |v| & mut v. 0 , SendRequestTask { request } )
523- . await
525+ SendRequestTask {
526+ request,
527+ _marker : marker:: PhantomData ,
528+ }
529+ . run ( accessor)
530+ . await
524531 }
525532}
526533
527- pub fn add_to_linker < T : WasiHttpView + ' static > ( linker : & mut Linker < T > ) -> wasmtime:: Result < ( ) > {
528- wasi:: http:: types:: add_to_linker_get_host ( linker, annotate_http ( |ctx| WasiHttpImpl ( ctx) ) ) ?;
529- wasi:: http:: handler:: add_to_linker_get_host ( linker, annotate_http ( |ctx| WasiHttpImpl ( ctx) ) )
530- }
534+ impl < T : WasiHttpView > wasi:: http:: handler:: Host for WasiHttpImpl < T > { }
531535
532- pub fn annotate_http < T , F > ( val : F ) -> F
536+ pub fn add_to_linker < T > ( linker : & mut Linker < T > ) -> wasmtime :: Result < ( ) >
533537where
534- F : Fn ( & mut T ) -> WasiHttpImpl < & mut T > ,
538+ T : for < ' a > WasiHttpViewConcurrent < View < ' a > = & ' a mut T > + ' static ,
539+ T : WasiHttpView ,
535540{
536- val
541+ wasi:: http:: types:: add_to_linker :: < T , WasiHttp < T > > ( linker, |x| WasiHttpImpl ( x) ) ?;
542+ wasi:: http:: handler:: add_to_linker :: < T , WasiHttp < T > > ( linker, |x| WasiHttpImpl ( x) ) ?;
543+ Ok ( ( ) )
537544}
0 commit comments