wasmedge_sys/store.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
//! Defines WasmEdge Store struct.
use crate::{
ffi,
instance::{
module::{InnerInstance, Instance},
InnerRef,
},
types::WasmEdgeString,
WasmEdgeResult,
};
use wasmedge_types::error::{StoreError, WasmEdgeError};
/// The [Store] is a collection of registered modules and assists wasm modules in finding the import modules they need.
#[derive(Debug)]
pub struct Store {
pub(crate) inner: InnerStore,
}
impl Store {
/// Creates a new [Store].
///
/// # Error
///
/// If fail to create, then an error is returned.
pub fn create() -> WasmEdgeResult<Self> {
let ctx = unsafe { ffi::WasmEdge_StoreCreate() };
match ctx.is_null() {
true => Err(Box::new(WasmEdgeError::Store(StoreError::Create))),
false => Ok(Store {
inner: InnerStore(ctx),
}),
}
}
/// Returns the length of the registered [modules](crate::Module).
pub fn module_len(&self) -> u32 {
unsafe { ffi::WasmEdge_StoreListModuleLength(self.inner.0 as *const _) }
}
/// Returns the names of all registered [modules](crate::Module).
pub fn module_names(&self) -> Option<Vec<String>> {
let len_mod_names = self.module_len();
match len_mod_names > 0 {
true => {
let mut mod_names = Vec::with_capacity(len_mod_names as usize);
unsafe {
ffi::WasmEdge_StoreListModule(
self.inner.0,
mod_names.as_mut_ptr(),
len_mod_names,
);
mod_names.set_len(len_mod_names as usize);
};
let names = mod_names
.into_iter()
.map(|x| x.into())
.collect::<Vec<String>>();
Some(names)
}
false => None,
}
}
/// Returns the module instance by the module name.
///
/// # Argument
///
/// * `name` - The name of the module instance to get.
///
/// # Error
///
/// If fail to find the target [module instance](crate::Instance), then an error is returned.
pub fn module(&self, name: impl AsRef<str>) -> WasmEdgeResult<InnerRef<Instance, &Self>> {
let mod_name: WasmEdgeString = name.as_ref().into();
let ctx = unsafe { ffi::WasmEdge_StoreFindModule(self.inner.0, mod_name.as_raw()) };
match ctx.is_null() {
true => Err(Box::new(WasmEdgeError::Store(StoreError::NotFoundModule(
name.as_ref().to_string(),
)))),
false => {
let inst = Instance {
inner: InnerInstance(ctx as _),
};
unsafe {
Ok(InnerRef::create_from_ref(
std::mem::ManuallyDrop::new(inst),
self,
))
}
}
}
}
/// Checks if the [Store] contains a module of which the name matches the given name.
///
/// # Argument
///
/// * `name` - The name of the module to search.
///
pub fn contains(&self, name: impl AsRef<str>) -> bool {
if self.module_len() == 0 {
return false;
}
match self.module_names() {
Some(names) => names.iter().any(|x| x == name.as_ref()),
None => false,
}
}
}
impl Drop for Store {
fn drop(&mut self) {
unsafe { ffi::WasmEdge_StoreDelete(self.inner.0) }
}
}
#[derive(Debug)]
pub(crate) struct InnerStore(pub(crate) *mut ffi::WasmEdge_StoreContext);
unsafe impl Send for InnerStore {}
unsafe impl Sync for InnerStore {}