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
pub use wasmtime_rust_macro::wasmtime;

// modules used by the macro
#[doc(hidden)]
pub mod __rt {
    pub use anyhow;
    pub use wasmtime;
    pub use wasmtime_wasi;

    use std::convert::{TryFrom, TryInto};

    pub trait FromVecValue: Sized {
        fn from(list: Vec<wasmtime::Val>) -> anyhow::Result<Self>;
    }

    macro_rules! tuple {
        ($(($($a:ident),*),)*) => ($(
            impl<$($a: TryFrom<wasmtime::Val>),*> FromVecValue for ($($a,)*)
                where $(anyhow::Error: From<$a::Error>,)*
            {
                #[allow(non_snake_case)]
                fn from(list: Vec<wasmtime::Val>) -> anyhow::Result<Self> {
                    let mut iter = list.into_iter();
                    $(
                        let $a = iter.next()
                            .ok_or_else(|| anyhow::format_err!("not enough values"))?
                            .try_into()?;
                    )*
                    if iter.next().is_some() {
                        anyhow::bail!("too many return values");
                    }
                    Ok(($($a,)*))
                }
            }
        )*)
    }

    tuple! {
        (),
        (A),
        (A, B),
        (A, B, C),
    }
}