use std::io::Cursor;
use stellar_xdr::{Limited, Limits, ReadXdr, ScMetaEntry};
use wasmparser::{BinaryReaderError, Parser, Payload};
pub fn parse_raw(meta: &[u8]) -> Result<Vec<ScMetaEntry>, stellar_xdr::Error> {
let limits = Limits::len(meta.len());
let reader = Cursor::new(meta);
let mut limited_reader = Limited::new(reader, limits);
let entries = ScMetaEntry::read_xdr_iter(&mut limited_reader).collect::<Result<Vec<_>, _>>()?;
Ok(entries)
}
#[derive(thiserror::Error, Debug)]
pub enum FromWasmError {
#[error("reading wasm")]
Read(BinaryReaderError),
#[error("parsing contract meta")]
Parse(stellar_xdr::Error),
}
pub fn raw_from_wasm(wasm: &[u8]) -> Result<Vec<u8>, FromWasmError> {
let mut meta = Vec::new();
for payload in Parser::new(0).parse_all(wasm) {
let payload = payload.map_err(FromWasmError::Read)?;
if let Payload::CustomSection(section) = payload {
if section.name() == "contractmetav0" {
meta.extend_from_slice(section.data());
}
}
}
Ok(meta)
}
pub fn from_wasm(wasm: &[u8]) -> Result<Vec<ScMetaEntry>, FromWasmError> {
let meta = raw_from_wasm(wasm)?;
parse_raw(&meta).map_err(FromWasmError::Parse)
}