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 {}