wasm_wave/value/
func.rs

1use alloc::{boxed::Box, string::String, vec::Vec};
2
3use crate::wasm::WasmFunc;
4
5use super::{Type, WasmValueError};
6
7/// A FuncType represents the parameter and result type(s) of a Wasm func.
8#[derive(Clone, PartialEq)]
9pub struct FuncType {
10    params: Vec<(String, Type)>,
11    results: Vec<(String, Type)>,
12}
13
14impl FuncType {
15    /// Returns a new FuncType with the given param and result type(s).
16    /// Returns an error if the resulting func type would be invalid in the
17    /// component model, e.g. has any unnamed results with more than one
18    /// result type.
19    pub fn new(
20        params: impl Into<Vec<(String, Type)>>,
21        results: impl Into<Vec<(String, Type)>>,
22    ) -> Result<Self, WasmValueError> {
23        let params = params.into();
24        if params.iter().any(|(name, _)| name.is_empty()) {
25            return Err(WasmValueError::Other("func params must be named".into()));
26        }
27        let results = results.into();
28        if results.len() > 1 && results.iter().any(|(name, _)| name.is_empty()) {
29            return Err(WasmValueError::Other(
30                "funcs with more than one result must have all results named".into(),
31            ));
32        }
33        Ok(Self { params, results })
34    }
35}
36
37impl WasmFunc for FuncType {
38    type Type = Type;
39
40    fn params(&self) -> Box<dyn Iterator<Item = Self::Type> + '_> {
41        Box::new(self.params.iter().map(|(_, ty)| ty.clone()))
42    }
43
44    fn param_names(&self) -> Box<dyn Iterator<Item = alloc::borrow::Cow<'_, str>> + '_> {
45        Box::new(self.params.iter().map(|(name, _)| name.into()))
46    }
47
48    fn results(&self) -> Box<dyn Iterator<Item = Self::Type> + '_> {
49        Box::new(self.results.iter().map(|(_, ty)| ty.clone()))
50    }
51
52    fn result_names(&self) -> Box<dyn Iterator<Item = alloc::borrow::Cow<'_, str>> + '_> {
53        Box::new(
54            self.results
55                .iter()
56                .flat_map(|(name, _)| (!name.is_empty()).then_some(name.into())),
57        )
58    }
59}
60
61impl core::fmt::Display for FuncType {
62    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
63        crate::wasm::DisplayFunc(self.clone()).fmt(f)
64    }
65}