Skip to main content

wasmedge_sys/
store.rs

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