wasm_link/
resource_wrapper.rs1use std::sync::Arc ;
2use thiserror::Error ;
3use wasmtime::component::{ Resource, ResourceAny, Val };
4use wasmtime::StoreContextMut ;
5
6use crate::PluginContext ;
7
8
9
10#[derive( Debug )]
11pub(crate) struct ResourceWrapper<Id> {
12 pub plugin_id: Id,
13 pub resource_handle: ResourceAny,
14}
15
16#[derive( Debug, Error )]
21pub enum ResourceCreationError {
22 #[error( "Resource Table Full" )] ResourceTableFull,
24 #[error( "Resource Handle Conversion Failed" )] ResourceHandleConversionFailed,
26}
27impl From<ResourceCreationError> for Val {
28 fn from( error: ResourceCreationError ) -> Self { match error {
29 ResourceCreationError::ResourceTableFull => Val::Variant( "resource-table-full".to_string(), None ),
30 ResourceCreationError::ResourceHandleConversionFailed => Val::Variant( "resource-handle-conversion-failed".to_string(), None ),
31 }}
32}
33
34#[derive( Debug, Error )]
40pub enum ResourceReceiveError {
41 #[error( "Invalid Handle" )] InvalidHandle,
43}
44impl From<ResourceReceiveError> for Val {
45 fn from( error: ResourceReceiveError ) -> Self { match error {
46 ResourceReceiveError::InvalidHandle => Val::Variant( "invalid-resource-handle".to_string(), None ),
47 }}
48}
49
50impl<Id: 'static + Send + Sync> ResourceWrapper<Id> {
51
52 pub(crate) fn new( plugin_id: Id, resource_handle: ResourceAny ) -> Self {
54 Self { plugin_id, resource_handle }
55 }
56
57 pub(crate) fn attach<Ctx: PluginContext>(
59 self,
60 store: &mut StoreContextMut<Ctx>,
61 ) -> Result<ResourceAny, ResourceCreationError> {
62 let table = store.data_mut().resource_table();
63 let resource = table.push( Arc::new( self )).map_err(|_| ResourceCreationError::ResourceTableFull )?;
64 ResourceAny::try_from_resource( resource, store )
65 .map_err(|_| ResourceCreationError::ResourceHandleConversionFailed )
66 }
67
68 pub(crate) fn from_handle<'a, Ctx: PluginContext>(
70 handle: ResourceAny,
71 store: &'a mut StoreContextMut<Ctx>,
72 ) -> Result<&'a Self, ResourceReceiveError> {
73 let resource = Resource::<Arc<Self>>::try_from_resource_any( handle, &mut *store ).map_err(|_| ResourceReceiveError::InvalidHandle )?;
74 let table = store.data_mut().resource_table();
75 let wrapped = table.get( &resource ).map_err(|_| ResourceReceiveError::InvalidHandle )?;
76 Ok( wrapped )
77 }
78
79 pub(crate) fn drop<Ctx: PluginContext>( mut ctx: StoreContextMut<Ctx>, handle: u32 ) -> Result<(), wasmtime::Error> {
81 let resource = Resource::<Arc<Self>>::new_own( handle );
82 let table = ctx.data_mut().resource_table();
83 table.delete( resource ).map_err(|_| wasmtime::Error::new( ResourceReceiveError::InvalidHandle ))?;
84 Ok(())
85 }
86
87}