1use crate::wit_type::{
2 TypeEnum, TypeFlags, TypeList, TypeOption, TypeRecord, TypeResult, TypeTuple, TypeVariant,
3 WitFunction, WitType,
4};
5use std::borrow::Cow;
6use wasm_wave::wasm::{WasmFunc, WasmType, WasmTypeKind};
7
8impl WasmType for WitType {
9 fn kind(&self) -> WasmTypeKind {
10 match self {
11 WitType::Bool(_) => WasmTypeKind::Bool,
12 WitType::S8(_) => WasmTypeKind::S8,
13 WitType::U8(_) => WasmTypeKind::U8,
14 WitType::S16(_) => WasmTypeKind::S16,
15 WitType::U16(_) => WasmTypeKind::U16,
16 WitType::S32(_) => WasmTypeKind::S32,
17 WitType::U32(_) => WasmTypeKind::U32,
18 WitType::S64(_) => WasmTypeKind::S64,
19 WitType::U64(_) => WasmTypeKind::U64,
20 WitType::F32(_) => WasmTypeKind::F32,
21 WitType::F64(_) => WasmTypeKind::F64,
22 WitType::Chr(_) => WasmTypeKind::Char,
23 WitType::Str(_) => WasmTypeKind::String,
24 WitType::List(_) => WasmTypeKind::List,
25 WitType::Tuple(_) => WasmTypeKind::Tuple,
26 WitType::Record(_) => WasmTypeKind::Record,
27 WitType::Flags(_) => WasmTypeKind::Flags,
28 WitType::Enum(_) => WasmTypeKind::Enum,
29 WitType::Option(_) => WasmTypeKind::Option,
30 WitType::Result { .. } => WasmTypeKind::Result,
31 WitType::Variant(_) => WasmTypeKind::Variant,
32 WitType::Handle(_) => WasmTypeKind::Unsupported,
33 }
34 }
35
36 fn list_element_type(&self) -> Option<Self> {
37 if let WitType::List(TypeList { inner: ty, .. }) = self {
38 Some(*ty.clone())
39 } else {
40 None
41 }
42 }
43
44 fn record_fields(&self) -> Box<dyn Iterator<Item = (Cow<'_, str>, Self)> + '_> {
45 if let WitType::Record(TypeRecord { fields, .. }) = self {
46 Box::new(
47 fields
48 .iter()
49 .map(|pair| (Cow::Borrowed(pair.name.as_str()), pair.typ.clone())),
50 )
51 } else {
52 Box::new(std::iter::empty())
53 }
54 }
55
56 fn tuple_element_types(&self) -> Box<dyn Iterator<Item = Self> + '_> {
57 if let WitType::Tuple(TypeTuple { items, .. }) = self {
58 Box::new(items.clone().into_iter())
59 } else {
60 Box::new(std::iter::empty())
61 }
62 }
63
64 fn variant_cases(&self) -> Box<dyn Iterator<Item = (Cow<'_, str>, Option<Self>)> + '_> {
65 if let WitType::Variant(TypeVariant { cases, .. }) = self {
66 Box::new(
67 cases
68 .iter()
69 .map(|case| (Cow::Borrowed(case.name.as_str()), case.typ.clone())),
70 )
71 } else {
72 Box::new(std::iter::empty())
73 }
74 }
75
76 fn enum_cases(&self) -> Box<dyn Iterator<Item = Cow<'_, str>> + '_> {
77 if let WitType::Enum(TypeEnum { cases, .. }) = self {
78 Box::new(cases.iter().map(|name| Cow::Borrowed(name.as_str())))
79 } else {
80 Box::new(std::iter::empty())
81 }
82 }
83
84 fn option_some_type(&self) -> Option<Self> {
85 if let WitType::Option(TypeOption { inner, .. }) = self {
86 Some(*inner.clone())
87 } else {
88 None
89 }
90 }
91
92 fn result_types(&self) -> Option<(Option<Self>, Option<Self>)> {
93 if let WitType::Result(TypeResult { ok, err, .. }) = self {
94 Some((
95 ok.as_ref().map(|t| *t.clone()),
96 err.as_ref().map(|t| *t.clone()),
97 ))
98 } else {
99 None
100 }
101 }
102
103 fn flags_names(&self) -> Box<dyn Iterator<Item = Cow<'_, str>> + '_> {
104 if let WitType::Flags(TypeFlags { names, .. }) = self {
105 Box::new(names.iter().map(|name| Cow::Borrowed(name.as_str())))
106 } else {
107 Box::new(std::iter::empty())
108 }
109 }
110}
111
112impl WasmFunc for WitFunction {
113 type Type = WitType;
114
115 fn params(&self) -> Box<dyn Iterator<Item = Self::Type> + '_> {
116 Box::new(self.parameters.iter().map(|p| p.typ.clone()))
117 }
118
119 fn param_names(&self) -> Box<dyn Iterator<Item = Cow<'_, str>> + '_> {
120 Box::new(
121 self.parameters
122 .iter()
123 .map(|p| Cow::Borrowed(p.name.as_str())),
124 )
125 }
126
127 fn results(&self) -> Box<dyn Iterator<Item = Self::Type> + '_> {
128 Box::new(self.result.iter().map(|r| r.typ.clone()))
129 }
130}