fce_module_info_parser/sdk_version/
version_embedder.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 crate::ModuleInfoResult;
18use crate::ModuleInfoError;
19use fluence_sdk_main::VERSION_SECTION_NAME;
20
21use walrus::ModuleConfig;
22use walrus::CustomSection;
23use walrus::IdsToIndices;
24
25use std::path::Path;
26use std::borrow::Cow;
27
28#[derive(Debug, Clone)]
29pub(super) struct VersionCustomSection(String);
30
31impl CustomSection for VersionCustomSection {
32    fn name(&self) -> &str {
33        VERSION_SECTION_NAME
34    }
35
36    fn data(&self, _ids_to_indices: &IdsToIndices) -> Cow<'_, [u8]> {
37        Cow::Borrowed(self.0.as_bytes())
38    }
39}
40
41/// Embed provided WIT to a Wasm module.
42pub fn embed_from_module(
43    mut wasm_module: walrus::Module,
44    version: &semver::Version,
45) -> walrus::Module {
46    delete_version_sections(&mut wasm_module);
47
48    let custom = VersionCustomSection(version.to_string());
49    wasm_module.customs.add(custom);
50
51    wasm_module
52}
53
54pub fn embed_from_path<I, O>(
55    in_wasm_module_path: I,
56    out_wasm_module_path: O,
57    version: &semver::Version,
58) -> ModuleInfoResult<()>
59where
60    I: AsRef<Path>,
61    O: AsRef<Path>,
62{
63    let wasm_module = ModuleConfig::new()
64        .parse_file(in_wasm_module_path)
65        .map_err(ModuleInfoError::CorruptedWasmFile)?;
66
67    let mut wasm_module = embed_from_module(wasm_module, version);
68    wasm_module
69        .emit_wasm_file(out_wasm_module_path)
70        .map_err(ModuleInfoError::WasmEmitError)
71}
72
73// TODO: deduplicate it with wit_parser::delete_wit_section_from_file
74fn delete_version_sections(wasm_module: &mut walrus::Module) {
75    let version_section_ids = wasm_module
76        .customs
77        .iter()
78        .filter_map(|(id, section)| {
79            if section.name() == VERSION_SECTION_NAME {
80                Some(id)
81            } else {
82                None
83            }
84        })
85        .collect::<Vec<_>>();
86
87    for id in version_section_ids {
88        wasm_module.customs.delete(id);
89    }
90}