fce_wit_parser/extractor/
functions.rs1use crate::Result;
18use crate::WITParserError;
19use fce_wit_interfaces::FCEWITInterfaces;
20
21use wasmer_wit::IRecordType;
22use wasmer_wit::ast::FunctionArg as IFunctionArg;
23use wasmer_wit::IType;
24use serde::Serialize;
25use serde::Deserialize;
26
27use std::collections::HashMap;
28use std::rc::Rc;
29
30pub type FCERecordTypes = HashMap<u64, Rc<IRecordType>>;
31
32#[derive(PartialEq, Eq, Debug, Clone, Hash, Serialize, Deserialize)]
33pub struct FCEFunctionSignature {
34 pub name: Rc<String>,
35 pub arguments: Rc<Vec<IFunctionArg>>,
36 pub outputs: Rc<Vec<IType>>,
37}
38
39#[derive(PartialEq, Eq, Debug, Clone, Serialize)]
40pub struct FCEModuleInterface {
41 pub record_types: FCERecordTypes,
42 pub function_signatures: Vec<FCEFunctionSignature>,
43}
44
45pub fn get_interface(fce_it_interface: &FCEWITInterfaces<'_>) -> Result<ServiceInterface> {
46 let fce_interface = get_raw_interface(fce_it_interface)?;
47 let service_interface = into_service_interface(fce_interface);
48
49 Ok(service_interface)
50}
51
52pub fn get_raw_interface(fce_it_interface: &FCEWITInterfaces<'_>) -> Result<FCEModuleInterface> {
53 let function_signatures = get_exports(fce_it_interface)?;
54 let record_types = extract_record_types(fce_it_interface);
55
56 let fce_interface = FCEModuleInterface {
57 record_types,
58 function_signatures,
59 };
60
61 Ok(fce_interface)
62}
63
64fn get_exports(wit: &FCEWITInterfaces<'_>) -> Result<Vec<FCEFunctionSignature>> {
65 use fce_wit_interfaces::WITAstType;
66
67 wit.implementations()
68 .filter_map(|(adapter_function_type, core_function_type)| {
69 wit.exports_by_type(*core_function_type)
70 .map(|export_function_name| (adapter_function_type, export_function_name))
71 })
72 .map(|(adapter_function_type, export_function_names)| {
73 export_function_names
74 .iter()
75 .map(move |export_function_name| (*adapter_function_type, export_function_name))
76 })
77 .flatten()
78 .map(|(adapter_function_type, export_function_name)| {
79 let wit_type = wit.type_by_idx_r(adapter_function_type).unwrap();
80
81 match wit_type {
82 WITAstType::Function {
83 arguments,
84 output_types,
85 } => {
86 let signature = FCEFunctionSignature {
87 name: Rc::new(export_function_name.to_string()),
88 arguments: arguments.clone(),
89 outputs: output_types.clone(),
90 };
91 Ok(signature)
92 }
93 _ => Err(WITParserError::IncorrectITFormat(format!(
94 "type with idx = {} isn't a function type",
95 adapter_function_type
96 ))),
97 }
98 })
99 .collect::<Result<Vec<FCEFunctionSignature>>>()
100}
101
102fn extract_record_types(wit: &FCEWITInterfaces<'_>) -> FCERecordTypes {
103 use fce_wit_interfaces::WITAstType;
104
105 let (record_types_by_id, _) = wit.types().fold(
106 (HashMap::new(), 0u64),
107 |(mut record_types_by_id, id), ty| {
108 match ty {
109 WITAstType::Record(record_type) => {
110 record_types_by_id.insert(id, record_type.clone());
111 }
112 WITAstType::Function { .. } => {}
113 };
114 (record_types_by_id, id + 1)
115 },
116 );
117
118 record_types_by_id
119}
120
121#[derive(Serialize)]
122pub struct FunctionSignature {
123 pub name: String,
124 pub arguments: Vec<(String, String)>,
125 pub output_types: Vec<String>,
126}
127
128#[derive(Serialize)]
129pub struct RecordType {
130 pub name: String,
131 pub id: u64,
132 pub fields: Vec<(String, String)>,
133}
134
135#[derive(Serialize)]
136pub struct ServiceInterface {
137 pub function_signatures: Vec<FunctionSignature>,
138 pub record_types: Vec<RecordType>,
139}
140
141pub(crate) fn into_service_interface(fce_interface: FCEModuleInterface) -> ServiceInterface {
142 let record_types = fce_interface.record_types;
143
144 let function_signatures = fce_interface
145 .function_signatures
146 .into_iter()
147 .map(|sign| serialize_function_signature(sign, &record_types))
148 .collect();
149
150 let record_types = record_types
151 .iter()
152 .map(|(id, record)| serialize_record_type(*id, record.clone(), &record_types))
153 .collect::<Vec<_>>();
154
155 ServiceInterface {
156 function_signatures,
157 record_types,
158 }
159}
160
161fn serialize_function_signature(
162 signature: FCEFunctionSignature,
163 record_types: &FCERecordTypes,
164) -> FunctionSignature {
165 let arguments = signature
166 .arguments
167 .iter()
168 .map(|arg| (arg.name.clone(), itype_text_view(&arg.ty, record_types)))
169 .collect();
170
171 let output_types = signature
172 .outputs
173 .iter()
174 .map(|itype| itype_text_view(itype, record_types))
175 .collect();
176
177 FunctionSignature {
178 name: signature.name.to_string(),
179 arguments,
180 output_types,
181 }
182}
183
184fn serialize_record_type(
185 id: u64,
186 record: Rc<IRecordType>,
187 record_types: &FCERecordTypes,
188) -> RecordType {
189 let fields = record
190 .fields
191 .iter()
192 .map(|field| (field.name.clone(), itype_text_view(&field.ty, record_types)))
193 .collect::<Vec<_>>();
194
195 RecordType {
196 name: record.name.clone(),
197 id,
198 fields,
199 }
200}
201
202fn itype_text_view(arg_ty: &IType, record_types: &FCERecordTypes) -> String {
203 match arg_ty {
204 IType::Record(record_type_id) => {
205 let record = record_types.get(record_type_id).unwrap();
208 record.name.clone()
209 }
210 IType::Array(array_ty) => format!("Array<{}>", itype_text_view(array_ty, record_types)),
211 t => format!("{:?}", t),
212 }
213}