Skip to main content

tinywasm_cli/
output.rs

1use tinywasm::types::{
2    ExportType, FuncType, GlobalType, ImportType, MemoryArch, MemoryType, TableType, WasmType, WasmValue,
3};
4
5pub fn print_results(results: &[WasmValue]) {
6    match results {
7        [] => {}
8        [value] => println!("{}", format_value(value)),
9        values => {
10            let formatted = values.iter().map(format_value).collect::<Vec<_>>().join(", ");
11            println!("[{formatted}]");
12        }
13    }
14}
15
16pub fn format_value(value: &WasmValue) -> String {
17    format!("{value:?}")
18}
19
20pub fn color_enabled() -> bool {
21    use std::io::IsTerminal;
22
23    std::io::stdout().is_terminal() && std::env::var_os("NO_COLOR").is_none()
24}
25
26pub fn format_wasm_type(ty: WasmType) -> &'static str {
27    match ty {
28        WasmType::I32 => "i32",
29        WasmType::I64 => "i64",
30        WasmType::F32 => "f32",
31        WasmType::F64 => "f64",
32        WasmType::V128 => "v128",
33        WasmType::RefFunc => "funcref",
34        WasmType::RefExtern => "externref",
35    }
36}
37
38pub fn format_func_type(ty: &FuncType) -> String {
39    let params = ty.params().iter().map(|ty| format_wasm_type(*ty)).collect::<Vec<_>>().join(", ");
40    let results = ty.results().iter().map(|ty| format_wasm_type(*ty)).collect::<Vec<_>>().join(", ");
41
42    if ty.results().is_empty() { format!("({params})") } else { format!("({params}) -> ({results})") }
43}
44
45pub fn format_memory_type(ty: &MemoryType) -> String {
46    let arch = match ty.arch() {
47        MemoryArch::I32 => "i32",
48        MemoryArch::I64 => "i64",
49    };
50    let max = if ty.page_count_max() == ty.page_count_initial() && ty.max_size() == ty.initial_size() {
51        ty.page_count_initial().to_string()
52    } else {
53        ty.page_count_max().to_string()
54    };
55
56    format!("memory[{arch}] initial={} max={} page_size={}", ty.page_count_initial(), max, ty.page_size())
57}
58
59pub fn format_table_type(ty: &TableType) -> String {
60    let max = ty.size_max.map(|v| v.to_string()).unwrap_or_else(|| "unbounded".to_string());
61    format!("table[{}] initial={} max={max}", format_wasm_type(ty.element_type), ty.size_initial)
62}
63
64pub fn format_global_type(ty: &GlobalType) -> String {
65    let mutability = if ty.mutable { "mut" } else { "const" };
66    format!("global[{mutability} {}]", format_wasm_type(ty.ty))
67}
68
69pub fn format_export_type(ty: ExportType<'_>) -> String {
70    match ty {
71        ExportType::Func(ty) => format!("func {}", format_func_type(ty)),
72        ExportType::Memory(ty) => format_memory_type(ty),
73        ExportType::Table(ty) => format_table_type(ty),
74        ExportType::Global(ty) => format_global_type(ty),
75    }
76}
77
78pub fn format_import_type(ty: ImportType<'_>) -> String {
79    match ty {
80        ImportType::Func(ty) => format!("func {}", format_func_type(ty)),
81        ImportType::Memory(ty) => format_memory_type(ty),
82        ImportType::Table(ty) => format_table_type(ty),
83        ImportType::Global(ty) => format_global_type(ty),
84    }
85}