soroban-meta 27.0.6

Soroban contract meta utilities.
Documentation
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)
}