fce_wit_parser/extractor/
wit.rs1use crate::custom::IT_SECTION_NAME;
18use crate::errors::WITParserError;
19use crate::Result;
20
21use walrus::IdsToIndices;
22use wasmer_wit::ast::Interfaces;
23use wasmer_core::Module as WasmerModule;
24
25use std::borrow::Cow;
26use std::path::Path;
27
28pub fn extract_text_wit<P>(wasm_file_path: P) -> Result<String>
30where
31 P: AsRef<Path>,
32{
33 let module = walrus::ModuleConfig::new()
34 .parse_file(wasm_file_path)
35 .map_err(WITParserError::CorruptedWasmFile)?;
36
37 let raw_custom_section = extract_custom_section(&module)?;
38 let wit_section_bytes = raw_custom_section.as_ref();
39 let wit = extract_wit_from_bytes(wit_section_bytes)?;
40
41 Ok((&wit).to_string())
42}
43
44pub fn extract_wit_from_module(wasmer_module: &WasmerModule) -> Result<Interfaces<'_>> {
46 let wit_sections = wasmer_module
47 .custom_sections(IT_SECTION_NAME)
48 .ok_or(WITParserError::NoITSection)?;
49
50 if wit_sections.len() > 1 {
51 return Err(WITParserError::MultipleITSections);
52 }
53
54 extract_wit_from_bytes(&wit_sections[0])
55}
56
57pub fn extract_version_from_module(module: &walrus::Module) -> Result<semver::Version> {
58 let raw_custom_section = extract_custom_section(&module)?;
59 let wit_section_bytes = raw_custom_section.as_ref();
60 let wit = extract_wit_from_bytes(wit_section_bytes)?;
61
62 Ok(wit.version)
63}
64
65pub(crate) fn extract_wit_from_bytes(wit_section_bytes: &[u8]) -> Result<Interfaces<'_>> {
66 match wasmer_wit::decoders::binary::parse::<(&[u8], nom::error::ErrorKind)>(wit_section_bytes) {
67 Ok((remainder, wit)) if remainder.is_empty() => Ok(wit),
68 Ok(_) => Err(WITParserError::ITRemainderNotEmpty),
69 Err(e) => Err(WITParserError::CorruptedITSection(e.to_owned())),
70 }
71}
72
73pub(crate) fn extract_custom_section(module: &walrus::Module) -> Result<Cow<'_, [u8]>> {
74 let sections = module
75 .customs
76 .iter()
77 .filter(|(_, section)| section.name() == IT_SECTION_NAME)
78 .collect::<Vec<_>>();
79
80 if sections.is_empty() {
81 return Err(WITParserError::NoITSection);
82 }
83 if sections.len() > 1 {
84 return Err(WITParserError::MultipleITSections);
85 }
86
87 let default_ids = IdsToIndices::default();
88 Ok(sections[0].1.data(&default_ids))
89}