1use std::io;
2
3use std::fmt::Write;
4
5use std::io::BufWriter;
6use std::io::Write as IoWrite;
7
8use std::io::Read;
9
10use wasmi::Engine;
11use wasmi::ExternType;
12use wasmi::Module;
13
14pub struct Runtime(pub Engine);
15
16impl Runtime {
17 pub fn create_module(&self, wasm_or_wat: &[u8]) -> Result<Module, io::Error> {
18 Module::new(&self.0, wasm_or_wat).map_err(io::Error::other)
19 }
20}
21
22#[derive(serde::Serialize)]
23pub struct ImportTypeDto<'a> {
24 pub module: &'a str,
25 pub name: &'a str,
26 pub extern_type: &'a str,
27}
28
29pub struct Parsed(pub Module);
30
31impl Parsed {
32 pub fn imports2writer<W>(&self, buf: &mut String, wtr: &mut W) -> Result<(), io::Error>
33 where
34 W: FnMut(ImportTypeDto) -> Result<(), io::Error>,
35 {
36 let imports = self.0.imports();
37 for ityp in imports {
38 let module: &str = ityp.module();
39 let name: &str = ityp.name();
40 let ty: &ExternType = ityp.ty();
41 buf.clear();
42 write!(buf, "{ty:?}").map_err(io::Error::other)?;
43 let extern_type: &str = buf;
44 let dto = ImportTypeDto {
45 module,
46 name,
47 extern_type,
48 };
49 wtr(dto)?;
50 }
51 Ok(())
52 }
53
54 pub fn imports2jsons2stdout(&self, buf: &mut String) -> Result<(), io::Error> {
55 let o = io::stdout();
56 let mut ol = o.lock();
57 let mut bw = BufWriter::new(&mut ol);
58 let mut wtr = |dto: ImportTypeDto| {
59 serde_json::to_writer(&mut bw, &dto)?;
60 writeln!(&mut bw)
61 };
62 self.imports2writer(buf, &mut wtr)?;
63 bw.flush()?;
64 drop(bw);
65 ol.flush()
66 }
67}
68
69pub fn reader2bytes_limited<R>(rdr: R, limit: u64) -> Result<Vec<u8>, io::Error>
70where
71 R: Read,
72{
73 let mut taken = rdr.take(limit);
74 let mut buf: Vec<u8> = vec![];
75 taken.read_to_end(&mut buf)?;
76 Ok(buf)
77}
78
79pub const WASM_OR_WAT_SIZE_LIMIT_DEFAULT: u64 = 16777216;
80
81pub fn stdin2bytes2engine2module2imports2jsons2stdout(limit: u64) -> Result<(), io::Error> {
82 let wasm_or_wat: Vec<u8> = reader2bytes_limited(io::stdin().lock(), limit)?;
83 let eng = Engine::default();
84 let module: Module = Runtime(eng).create_module(&wasm_or_wat)?;
85 let mut buf: String = String::new();
86 Parsed(module).imports2jsons2stdout(&mut buf)?;
87 Ok(())
88}