fce_module_info_parser/sdk_version/
version_extractor.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 super::SDKVersionError;
20use crate::extract_custom_sections_by_name;
21use crate::try_as_one_section;
22
23use wasmer_core::Module as WasmerModule;
24use fluence_sdk_main::VERSION_SECTION_NAME;
25use walrus::ModuleConfig;
26use walrus::Module;
27
28use std::borrow::Cow;
29use std::str::FromStr;
30use std::path::Path;
31
32pub fn extract_from_path<P>(wasm_module_path: P) -> ModuleInfoResult<Option<semver::Version>>
33where
34    P: AsRef<Path>,
35{
36    let module = ModuleConfig::new()
37        .parse_file(wasm_module_path)
38        .map_err(ModuleInfoError::CorruptedWasmFile)?;
39
40    extract_from_module(&module)
41}
42
43pub fn extract_from_module(wasm_module: &Module) -> ModuleInfoResult<Option<semver::Version>> {
44    let sections = extract_custom_sections_by_name(&wasm_module, VERSION_SECTION_NAME)?;
45
46    if sections.is_empty() {
47        return Ok(None);
48    }
49    let section = try_as_one_section(&sections, VERSION_SECTION_NAME)?;
50
51    let version = match section {
52        Cow::Borrowed(bytes) => as_semver(bytes),
53        Cow::Owned(vec) => as_semver(&vec),
54    }?;
55
56    Ok(Some(version))
57}
58
59pub fn extract_from_wasmer_module(
60    wasmer_module: &WasmerModule,
61) -> ModuleInfoResult<Option<semver::Version>> {
62    let sections = wasmer_module.custom_sections(VERSION_SECTION_NAME);
63
64    let sections = match sections {
65        Some(sections) => sections,
66        None => return Ok(None),
67    };
68
69    let section = try_as_one_section(sections, VERSION_SECTION_NAME)?;
70    let version = as_semver(section)?;
71
72    Ok(Some(version))
73}
74
75fn as_semver(version_as_bytes: &[u8]) -> Result<semver::Version, super::SDKVersionError> {
76    match std::str::from_utf8(version_as_bytes) {
77        Ok(str) => Ok(semver::Version::from_str(str)?),
78        Err(e) => Err(SDKVersionError::VersionNotValidUtf8(e)),
79    }
80}