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 #[must_use]
18 pub const fn new(index: u32) -> Self {
19 Self(index)
20 }
21
22 #[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#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
43pub struct ParameterList(Vec<FunctionValueType>);
44
45impl ParameterList {
46 #[must_use]
48 pub fn new(values: Vec<FunctionValueType>) -> Self {
49 Self(values)
50 }
51
52 #[must_use]
54 pub const fn empty() -> Self {
55 Self(Vec::new())
56 }
57
58 #[must_use]
60 pub fn as_slice(&self) -> &[FunctionValueType] {
61 &self.0
62 }
63
64 #[must_use]
66 pub fn len(&self) -> usize {
67 self.0.len()
68 }
69
70 #[must_use]
72 pub fn is_empty(&self) -> bool {
73 self.0.is_empty()
74 }
75}
76
77#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
79pub struct ResultList(Vec<FunctionValueType>);
80
81impl ResultList {
82 #[must_use]
84 pub fn new(values: Vec<FunctionValueType>) -> Self {
85 Self(values)
86 }
87
88 #[must_use]
90 pub const fn empty() -> Self {
91 Self(Vec::new())
92 }
93
94 #[must_use]
96 pub fn as_slice(&self) -> &[FunctionValueType] {
97 &self.0
98 }
99}
100
101#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
103pub struct FunctionSignature {
104 params: ParameterList,
105 results: ResultList,
106}
107
108impl FunctionSignature {
109 #[must_use]
111 pub const fn new(params: ParameterList, results: ResultList) -> Self {
112 Self { params, results }
113 }
114
115 #[must_use]
117 pub const fn params(&self) -> &ParameterList {
118 &self.params
119 }
120
121 #[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}