41
41
//! let mut linker = Linker::<Ctx>::new(&engine);
42
42
//! wasmtime_wasi::add_to_linker_async(&mut linker)?;
43
43
//! // add `wasi-runtime-config` world's interfaces to the linker
44
- //! wasmtime_wasi_keyvalue::add_to_linker (&mut linker, |h: &mut Ctx| {
44
+ //! wasmtime_wasi_keyvalue::add_to_linker_async (&mut linker, |h: &mut Ctx| {
45
45
//! WasiKeyValue::new(&h.wasi_keyvalue_ctx, &mut h.table)
46
46
//! })?;
47
47
//!
68
68
69
69
#![ deny( missing_docs) ]
70
70
71
+ mod bindings;
71
72
mod provider;
72
- mod generated {
73
- wasmtime:: component:: bindgen!( {
74
- path: "wit" ,
75
- world: "wasi:keyvalue/imports" ,
76
- trappable_imports: true ,
77
- async : true ,
78
- with: {
79
- "wasi:keyvalue/store/bucket" : crate :: Bucket ,
80
- } ,
81
- trappable_error_type: {
82
- "wasi:keyvalue/store/error" => crate :: Error ,
83
- } ,
84
- } ) ;
85
- }
86
73
87
- use self :: generated :: wasi:: keyvalue;
74
+ use self :: bindings :: { sync :: wasi:: keyvalue as keyvalue_sync , wasi :: keyvalue } ;
88
75
use anyhow:: Result ;
89
76
use async_trait:: async_trait;
90
77
use std:: collections:: HashMap ;
91
78
use std:: fmt:: Display ;
92
79
use url:: Url ;
93
80
use wasmtime:: component:: { Resource , ResourceTable , ResourceTableError } ;
81
+ use wasmtime_wasi:: runtime:: in_tokio;
94
82
95
83
#[ doc( hidden) ]
96
84
pub enum Error {
@@ -411,7 +399,12 @@ impl keyvalue::batch::Host for WasiKeyValue<'_> {
411
399
}
412
400
413
401
/// Add all the `wasi-keyvalue` world's interfaces to a [`wasmtime::component::Linker`].
414
- pub fn add_to_linker < T : Send > (
402
+ ///
403
+ /// This function will add the `async` variant of all interfaces into the
404
+ /// `Linker` provided. By `async` this means that this function is only
405
+ /// compatible with [`Config::async_support(true)`][wasmtime::Config::async_support].
406
+ /// For embeddings with async support disabled see [`add_to_linker_sync`] instead.
407
+ pub fn add_to_linker_async < T : Send > (
415
408
l : & mut wasmtime:: component:: Linker < T > ,
416
409
f : impl Fn ( & mut T ) -> WasiKeyValue < ' _ > + Send + Sync + Copy + ' static ,
417
410
) -> Result < ( ) > {
@@ -421,6 +414,104 @@ pub fn add_to_linker<T: Send>(
421
414
Ok ( ( ) )
422
415
}
423
416
417
+ impl keyvalue_sync:: store:: Host for WasiKeyValue < ' _ > {
418
+ fn open ( & mut self , identifier : String ) -> Result < Resource < Bucket > , Error > {
419
+ in_tokio ( async { keyvalue:: store:: Host :: open ( self , identifier) . await } )
420
+ }
421
+
422
+ fn convert_error ( & mut self , err : Error ) -> Result < keyvalue_sync:: store:: Error > {
423
+ match err {
424
+ Error :: NoSuchStore => Ok ( keyvalue_sync:: store:: Error :: NoSuchStore ) ,
425
+ Error :: AccessDenied => Ok ( keyvalue_sync:: store:: Error :: AccessDenied ) ,
426
+ Error :: Other ( e) => Ok ( keyvalue_sync:: store:: Error :: Other ( e) ) ,
427
+ }
428
+ }
429
+ }
430
+
431
+ impl keyvalue_sync:: store:: HostBucket for WasiKeyValue < ' _ > {
432
+ fn get ( & mut self , bucket : Resource < Bucket > , key : String ) -> Result < Option < Vec < u8 > > , Error > {
433
+ in_tokio ( async { keyvalue:: store:: HostBucket :: get ( self , bucket, key) . await } )
434
+ }
435
+
436
+ fn set ( & mut self , bucket : Resource < Bucket > , key : String , value : Vec < u8 > ) -> Result < ( ) , Error > {
437
+ in_tokio ( async { keyvalue:: store:: HostBucket :: set ( self , bucket, key, value) . await } )
438
+ }
439
+
440
+ fn delete ( & mut self , bucket : Resource < Bucket > , key : String ) -> Result < ( ) , Error > {
441
+ in_tokio ( async { keyvalue:: store:: HostBucket :: delete ( self , bucket, key) . await } )
442
+ }
443
+
444
+ fn exists ( & mut self , bucket : Resource < Bucket > , key : String ) -> Result < bool , Error > {
445
+ in_tokio ( async { keyvalue:: store:: HostBucket :: exists ( self , bucket, key) . await } )
446
+ }
447
+
448
+ fn list_keys (
449
+ & mut self ,
450
+ bucket : Resource < Bucket > ,
451
+ cursor : Option < u64 > ,
452
+ ) -> Result < keyvalue_sync:: store:: KeyResponse , Error > {
453
+ in_tokio ( async {
454
+ let resp = keyvalue:: store:: HostBucket :: list_keys ( self , bucket, cursor) . await ?;
455
+ Ok ( keyvalue_sync:: store:: KeyResponse {
456
+ keys : resp. keys ,
457
+ cursor : resp. cursor ,
458
+ } )
459
+ } )
460
+ }
461
+
462
+ fn drop ( & mut self , bucket : Resource < Bucket > ) -> Result < ( ) > {
463
+ keyvalue:: store:: HostBucket :: drop ( self , bucket)
464
+ }
465
+ }
466
+
467
+ impl keyvalue_sync:: atomics:: Host for WasiKeyValue < ' _ > {
468
+ fn increment (
469
+ & mut self ,
470
+ bucket : Resource < Bucket > ,
471
+ key : String ,
472
+ delta : u64 ,
473
+ ) -> Result < u64 , Error > {
474
+ in_tokio ( async { keyvalue:: atomics:: Host :: increment ( self , bucket, key, delta) . await } )
475
+ }
476
+ }
477
+
478
+ impl keyvalue_sync:: batch:: Host for WasiKeyValue < ' _ > {
479
+ fn get_many (
480
+ & mut self ,
481
+ bucket : Resource < Bucket > ,
482
+ keys : Vec < String > ,
483
+ ) -> Result < Vec < Option < ( String , Vec < u8 > ) > > , Error > {
484
+ in_tokio ( async { keyvalue:: batch:: Host :: get_many ( self , bucket, keys) . await } )
485
+ }
486
+
487
+ fn set_many (
488
+ & mut self ,
489
+ bucket : Resource < Bucket > ,
490
+ key_values : Vec < ( String , Vec < u8 > ) > ,
491
+ ) -> Result < ( ) , Error > {
492
+ in_tokio ( async { keyvalue:: batch:: Host :: set_many ( self , bucket, key_values) . await } )
493
+ }
494
+
495
+ fn delete_many ( & mut self , bucket : Resource < Bucket > , keys : Vec < String > ) -> Result < ( ) , Error > {
496
+ in_tokio ( async { keyvalue:: batch:: Host :: delete_many ( self , bucket, keys) . await } )
497
+ }
498
+ }
499
+
500
+ /// Add all the `wasi-keyvalue` world's interfaces to a [`wasmtime::component::Linker`].
501
+ ///
502
+ /// This function will add the `sync` variant of all interfaces into the
503
+ /// `Linker` provided. For embeddings with async support see
504
+ /// [`add_to_linker_async`] instead.
505
+ pub fn add_to_linker_sync < T > (
506
+ l : & mut wasmtime:: component:: Linker < T > ,
507
+ f : impl Fn ( & mut T ) -> WasiKeyValue < ' _ > + Send + Sync + Copy + ' static ,
508
+ ) -> Result < ( ) > {
509
+ keyvalue_sync:: store:: add_to_linker_get_host ( l, f) ?;
510
+ keyvalue_sync:: atomics:: add_to_linker_get_host ( l, f) ?;
511
+ keyvalue_sync:: batch:: add_to_linker_get_host ( l, f) ?;
512
+ Ok ( ( ) )
513
+ }
514
+
424
515
#[ cfg( test) ]
425
516
mod tests {
426
517
#[ test]
0 commit comments