marine_module_info_parser/
effects.rs

1/*
2 * Copyright 2024 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 crate::ModuleInfoResult;
18use crate::ModuleInfoError;
19
20use walrus::ModuleConfig;
21use walrus::Module;
22
23use std::path::Path;
24
25// TODO: create a common place for these consts to use in both marine and marine-rs-sdk to use in both marine and marine-rs-sdk
26const HOST_IMPORT_NAMESPACE_V0: &str = "host";
27const HOST_IMPORT_NAMESPACE_PREFIX: &str = "__marine_host_api_v";
28const LOGGER_IMPORT_NAME: &str = "log_utf8_string";
29const CALL_PARAMETERS_IMPORT_NAME: &str = "get_call_parameters";
30
31#[derive(Debug)]
32pub enum WasmEffect {
33    Logger,
34    MountedBinary(String),
35}
36
37pub fn extract_from_path<P>(wasm_module_path: P) -> ModuleInfoResult<Vec<WasmEffect>>
38where
39    P: AsRef<Path>,
40{
41    let module = ModuleConfig::new()
42        .parse_file(wasm_module_path)
43        .map_err(ModuleInfoError::CorruptedWasmFile)?;
44
45    extract_from_module(&module)
46}
47
48pub fn extract_from_bytes(wasm_module_bytes: &[u8]) -> ModuleInfoResult<Vec<WasmEffect>> {
49    let module = ModuleConfig::new()
50        .parse(wasm_module_bytes)
51        .map_err(ModuleInfoError::CorruptedWasmFile)?;
52
53    extract_from_module(&module)
54}
55
56pub fn extract_from_module(wasm_module: &Module) -> ModuleInfoResult<Vec<WasmEffect>> {
57    let effects = wasm_module
58        .imports
59        .iter()
60        .filter_map(|import| inspect_import(&import.module, &import.name))
61        .collect();
62
63    Ok(effects)
64}
65
66fn inspect_import(module: &str, name: &str) -> Option<WasmEffect> {
67    if !is_host_import(module) {
68        return None;
69    }
70
71    match name {
72        LOGGER_IMPORT_NAME => Some(WasmEffect::Logger),
73        CALL_PARAMETERS_IMPORT_NAME => None,
74        name => Some(WasmEffect::MountedBinary(name.to_string())),
75    }
76}
77
78fn is_host_import(namespace: &str) -> bool {
79    namespace == HOST_IMPORT_NAMESPACE_V0 || namespace.starts_with(HOST_IMPORT_NAMESPACE_PREFIX)
80}