1use crate::wasm::WasmFunc;
2
3use super::{Type, WasmValueError};
4
5#[derive(Clone, PartialEq)]
7pub struct FuncType {
8 params: Vec<(String, Type)>,
9 results: Vec<(String, Type)>,
10}
11
12impl FuncType {
13 pub fn new(
18 params: impl Into<Vec<(String, Type)>>,
19 results: impl Into<Vec<(String, Type)>>,
20 ) -> Result<Self, WasmValueError> {
21 let params = params.into();
22 if params.iter().any(|(name, _)| name.is_empty()) {
23 return Err(WasmValueError::Other("func params must be named".into()));
24 }
25 let results = results.into();
26 if results.len() > 1 && results.iter().any(|(name, _)| name.is_empty()) {
27 return Err(WasmValueError::Other(
28 "funcs with more than one result must have all results named".into(),
29 ));
30 }
31 Ok(Self { params, results })
32 }
33}
34
35impl WasmFunc for FuncType {
36 type Type = Type;
37
38 fn params(&self) -> Box<dyn Iterator<Item = Self::Type> + '_> {
39 Box::new(self.params.iter().map(|(_, ty)| ty.clone()))
40 }
41
42 fn param_names(&self) -> Box<dyn Iterator<Item = std::borrow::Cow<'_, str>> + '_> {
43 Box::new(self.params.iter().map(|(name, _)| name.into()))
44 }
45
46 fn results(&self) -> Box<dyn Iterator<Item = Self::Type> + '_> {
47 Box::new(self.results.iter().map(|(_, ty)| ty.clone()))
48 }
49
50 fn result_names(&self) -> Box<dyn Iterator<Item = std::borrow::Cow<'_, str>> + '_> {
51 Box::new(
52 self.results
53 .iter()
54 .flat_map(|(name, _)| (!name.is_empty()).then_some(name.into())),
55 )
56 }
57}
58
59impl std::fmt::Display for FuncType {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 crate::wasm::DisplayFunc(self.clone()).fmt(f)
62 }
63}