Skip to main content

use_wasm_function/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use core::fmt;
5
6pub use use_wasm_value::{
7    WasmValueType as FunctionValueType, WasmValueTypeError as WasmFunctionError,
8};
9
10macro_rules! index_newtype {
11    ($name:ident) => {
12        #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
13        pub struct $name(u32);
14
15        impl $name {
16            /// Creates an index wrapper.
17            #[must_use]
18            pub const fn new(index: u32) -> Self {
19                Self(index)
20            }
21
22            /// Returns the wrapped index.
23            #[must_use]
24            pub const fn get(self) -> u32 {
25                self.0
26            }
27        }
28
29        impl fmt::Display for $name {
30            fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
31                write!(formatter, "{}", self.get())
32            }
33        }
34    };
35}
36
37index_newtype!(FunctionIndex);
38index_newtype!(TypeIndex);
39index_newtype!(LocalIndex);
40
41/// Function parameter list metadata.
42#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
43pub struct ParameterList(Vec<FunctionValueType>);
44
45impl ParameterList {
46    /// Creates a parameter list from value type labels.
47    #[must_use]
48    pub fn new(values: Vec<FunctionValueType>) -> Self {
49        Self(values)
50    }
51
52    /// Returns an empty parameter list.
53    #[must_use]
54    pub const fn empty() -> Self {
55        Self(Vec::new())
56    }
57
58    /// Returns the parameter list as a slice.
59    #[must_use]
60    pub fn as_slice(&self) -> &[FunctionValueType] {
61        &self.0
62    }
63
64    /// Returns the number of parameters.
65    #[must_use]
66    pub fn len(&self) -> usize {
67        self.0.len()
68    }
69
70    /// Returns 'true' when no parameters are present.
71    #[must_use]
72    pub fn is_empty(&self) -> bool {
73        self.0.is_empty()
74    }
75}
76
77/// Function result list metadata.
78#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
79pub struct ResultList(Vec<FunctionValueType>);
80
81impl ResultList {
82    /// Creates a result list from value type labels.
83    #[must_use]
84    pub fn new(values: Vec<FunctionValueType>) -> Self {
85        Self(values)
86    }
87
88    /// Returns an empty result list.
89    #[must_use]
90    pub const fn empty() -> Self {
91        Self(Vec::new())
92    }
93
94    /// Returns the result list as a slice.
95    #[must_use]
96    pub fn as_slice(&self) -> &[FunctionValueType] {
97        &self.0
98    }
99}
100
101/// Function signature metadata.
102#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
103pub struct FunctionSignature {
104    params: ParameterList,
105    results: ResultList,
106}
107
108impl FunctionSignature {
109    /// Creates function signature metadata.
110    #[must_use]
111    pub const fn new(params: ParameterList, results: ResultList) -> Self {
112        Self { params, results }
113    }
114
115    /// Returns parameter metadata.
116    #[must_use]
117    pub const fn params(&self) -> &ParameterList {
118        &self.params
119    }
120
121    /// Returns result metadata.
122    #[must_use]
123    pub const fn results(&self) -> &ResultList {
124        &self.results
125    }
126}
127
128#[cfg(test)]
129mod tests {
130    use super::{
131        FunctionIndex, FunctionSignature, FunctionValueType, ParameterList, ResultList,
132        WasmFunctionError,
133    };
134
135    #[test]
136    fn wraps_indexes_and_value_types() {
137        let index = FunctionIndex::new(3);
138        let value_type = "extern-ref"
139            .parse::<FunctionValueType>()
140            .expect("known type");
141
142        assert_eq!(index.get(), 3);
143        assert_eq!(index.to_string(), "3");
144        assert_eq!(value_type, FunctionValueType::ExternRef);
145        assert_eq!(
146            "".parse::<FunctionValueType>(),
147            Err(WasmFunctionError::Empty)
148        );
149    }
150
151    #[test]
152    fn stores_signature_metadata() {
153        let signature = FunctionSignature::new(
154            ParameterList::new(vec![FunctionValueType::I32, FunctionValueType::I64]),
155            ResultList::new(vec![FunctionValueType::I32]),
156        );
157
158        assert_eq!(signature.params().len(), 2);
159        assert_eq!(signature.results().as_slice(), &[FunctionValueType::I32]);
160    }
161}