1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#![feature(box_syntax)]

#[macro_use]
extern crate serde;

mod idl;

#[cfg(feature = "import")]
pub mod import;
#[cfg(feature = "visitor")]
pub mod visitor;

#[cfg(feature = "saveload")]
use anyhow::{anyhow, Result};

pub use idl::*;

#[cfg(feature = "saveload")]
impl Interface {
    pub fn from_slice(sl: &[u8]) -> Result<crate::Interface> {
        use std::io::Read as _;
        let mut decoder = libflate::deflate::Decoder::new(sl);
        let mut inflated = Vec::new();
        decoder.read_to_end(&mut inflated)?;
        Ok(serde_json::from_slice(&inflated)?)
    }

    pub fn to_vec(&self) -> Result<Vec<u8>> {
        let mut encoder = libflate::deflate::Encoder::new(Vec::new());
        serde_json::to_writer(&mut encoder, self)?;
        Ok(encoder.finish().into_result()?)
    }

    pub fn to_string(&self) -> Result<String> {
        Ok(serde_json::to_string_pretty(self)?)
    }

    pub fn from_wasm_bytecode(bytecode: &[u8]) -> Result<Self> {
        wasmparser::ModuleReader::new(bytecode)?
            .into_iter()
            .find_map(|section| {
                if let Ok(wasmparser::Section {
                    code:
                        wasmparser::SectionCode::Custom {
                            name: "oasis-interface",
                            ..
                        },
                    ..
                }) = section
                {
                    let section = section.unwrap();
                    let mut reader = section.get_binary_reader();
                    Some(reader.read_bytes(reader.bytes_remaining()).unwrap())
                } else {
                    None
                }
            })
            .ok_or_else(|| anyhow!("missing oasis-interface section"))
            .and_then(Self::from_slice)
    }
}