fce_wit_interfaces/
fce_wit_interfaces.rs

1/*
2 * Copyright 2020 Fluence Labs Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use super::errors::FCEWITInterfacesError;
18
19use wasmer_wit::interpreter::Instruction;
20use wasmer_wit::ast::*;
21use wasmer_wit::IRecordType;
22use multimap::MultiMap;
23
24use std::iter::Iterator;
25use std::collections::HashMap;
26use std::rc::Rc;
27
28pub type CoreFunctionType = u32;
29pub type AdapterFunctionType = u32;
30pub type ExportName<'a> = &'a str;
31pub type ImportName<'a> = &'a str;
32pub type ImportNamespace<'a> = &'a str;
33pub type WITAstType = Type;
34
35pub struct FCEWITInterfaces<'a> {
36    /// All the types.
37    types: Vec<WITAstType>,
38
39    /// All the imported functions.
40    imports: Vec<Import<'a>>,
41    core_type_to_imports: MultiMap<CoreFunctionType, (ImportName<'a>, ImportNamespace<'a>)>,
42
43    /// All the adapters.
44    adapters: HashMap<AdapterFunctionType, Vec<Instruction>>,
45
46    /// All the exported functions.
47    exports: Vec<Export<'a>>,
48    core_type_to_exports: MultiMap<CoreFunctionType, ExportName<'a>>,
49
50    /// All the implementations.
51    adapter_type_to_core: MultiMap<AdapterFunctionType, CoreFunctionType>,
52    core_type_to_adapter: MultiMap<CoreFunctionType, AdapterFunctionType>,
53}
54
55impl<'a> FCEWITInterfaces<'a> {
56    pub fn new(interfaces: Interfaces<'a>) -> Self {
57        let core_type_to_imports = interfaces
58            .imports
59            .iter()
60            .map(|import| (import.function_type, (import.namespace, import.name)))
61            .collect::<MultiMap<_, _>>();
62
63        let adapters = interfaces
64            .adapters
65            .into_iter()
66            .map(|adapter| (adapter.function_type, adapter.instructions))
67            .collect::<HashMap<_, _>>();
68
69        let core_type_to_exports = interfaces
70            .exports
71            .iter()
72            .map(|export| (export.function_type, export.name))
73            .collect::<MultiMap<_, _>>();
74
75        let adapter_type_to_core = interfaces
76            .implementations
77            .iter()
78            .map(|implementation| {
79                (
80                    implementation.adapter_function_type,
81                    implementation.core_function_type,
82                )
83            })
84            .collect::<MultiMap<_, _>>();
85
86        let core_type_to_adapter = interfaces
87            .implementations
88            .iter()
89            .map(|implementation| {
90                (
91                    implementation.core_function_type,
92                    implementation.adapter_function_type,
93                )
94            })
95            .collect::<MultiMap<_, _>>();
96
97        Self {
98            types: interfaces.types,
99            imports: interfaces.imports,
100            core_type_to_imports,
101            adapters,
102            exports: interfaces.exports,
103            core_type_to_exports,
104            adapter_type_to_core,
105            core_type_to_adapter,
106        }
107    }
108
109    pub fn types(&self) -> impl Iterator<Item = &Type> {
110        self.types.iter()
111    }
112
113    pub fn record_types(&self) -> impl Iterator<Item = (u64, &Rc<IRecordType>)> {
114        self.types.iter().enumerate().filter_map(|(id, t)| match t {
115            WITAstType::Record(r) => Some((id as u64, r)),
116            _ => None,
117        })
118    }
119
120    pub fn type_by_idx(&self, idx: u32) -> Option<&Type> {
121        self.types.get(idx as usize)
122    }
123
124    pub fn type_by_idx_r(&self, idx: u32) -> Result<&Type, FCEWITInterfacesError> {
125        self.types
126            .get(idx as usize)
127            .ok_or(FCEWITInterfacesError::NoSuchType(idx))
128    }
129
130    pub fn imports(&self) -> impl Iterator<Item = &Import<'_>> {
131        self.imports.iter()
132    }
133
134    pub fn imports_by_type(
135        &self,
136        import_type: CoreFunctionType,
137    ) -> Option<&Vec<(ImportName<'a>, ImportNamespace<'a>)>> {
138        self.core_type_to_imports.get_vec(&import_type)
139    }
140
141    pub fn imports_by_type_r(
142        &self,
143        import_type: CoreFunctionType,
144    ) -> Result<&Vec<(ImportName<'a>, ImportNamespace<'a>)>, FCEWITInterfacesError> {
145        self.core_type_to_imports
146            .get_vec(&import_type)
147            .ok_or(FCEWITInterfacesError::NoSuchImport(import_type))
148    }
149
150    pub fn adapters(&self) -> impl Iterator<Item = (&AdapterFunctionType, &Vec<Instruction>)> {
151        self.adapters.iter()
152    }
153
154    pub fn adapter_by_type(&self, adapter_type: AdapterFunctionType) -> Option<&Vec<Instruction>> {
155        self.adapters.get(&adapter_type)
156    }
157
158    pub fn adapter_by_type_r(
159        &self,
160        adapter_type: AdapterFunctionType,
161    ) -> Result<&Vec<Instruction>, FCEWITInterfacesError> {
162        self.adapters
163            .get(&adapter_type)
164            .ok_or(FCEWITInterfacesError::NoSuchAdapter(adapter_type))
165    }
166
167    pub fn exports(&self) -> impl Iterator<Item = &Export<'_>> {
168        self.exports.iter()
169    }
170
171    pub fn exports_by_type(&self, export_type: u32) -> Option<&Vec<ExportName<'a>>> {
172        self.core_type_to_exports.get_vec(&export_type)
173    }
174
175    pub fn exports_by_type_r(
176        &self,
177        export_type: CoreFunctionType,
178    ) -> Result<&Vec<ExportName<'a>>, FCEWITInterfacesError> {
179        self.core_type_to_exports
180            .get_vec(&export_type)
181            .ok_or(FCEWITInterfacesError::NoSuchImport(export_type))
182    }
183
184    pub fn implementations(
185        &self,
186    ) -> impl Iterator<Item = (&AdapterFunctionType, &CoreFunctionType)> {
187        self.adapter_type_to_core.iter()
188    }
189
190    pub fn adapter_types_by_core_type(
191        &self,
192        core_function_type: CoreFunctionType,
193    ) -> Option<&Vec<AdapterFunctionType>> {
194        self.core_type_to_adapter.get_vec(&core_function_type)
195    }
196
197    pub fn core_types_by_adapter_type(
198        &self,
199        adapter_function_type: AdapterFunctionType,
200    ) -> Option<&Vec<CoreFunctionType>> {
201        self.adapter_type_to_core.get_vec(&adapter_function_type)
202    }
203}