use anyhow::{anyhow, bail, Context, Result};
use serde::Deserialize;
use std::path::Path;
use wasmtime::wasmparser::{Parser, Payload};
use crate::file_matching::MatchExpression;
#[derive(Debug, Deserialize)]
pub struct ArgBlock {
pub name: String,
pub args: Vec<String>,
}
#[derive(Debug, Deserialize)]
pub struct NitMetadata {
pub argv0: String,
pub max_filenames: u64,
pub require_serial: bool,
pub args: Vec<ArgBlock>,
pub default_match: MatchExpression,
pub repo: String,
}
pub fn read_metadata(wasm_path: &Path) -> Result<NitMetadata> {
let module = std::fs::read(wasm_path)?;
let parser = Parser::new(0);
for payload in parser.parse_all(&module) {
match payload? {
Payload::CustomSection(section) if section.name() == "nit_metadata" => {
return Ok(serde_json::from_slice::<NitMetadata>(section.data()).with_context(|| anyhow!("Reading metadata for {}", wasm_path.display()))?);
}
_ => {}
}
}
bail!("No nit_metadata section found in the wasm file");
}
pub fn has_metadata(module: &[u8]) -> Result<bool> {
let parser = Parser::new(0);
for payload in parser.parse_all(&module) {
match payload? {
Payload::CustomSection(section) if section.name() == "nit_metadata" => {
return Ok(true);
}
_ => {}
}
}
Ok(false)
}