#[macro_export]
macro_rules! extract_bin {
($value:expr, $err:expr) => {
match $value {
$crate::Value::Bin { data, .. } => data.as_ref(),
_ => return Err($crate::Error::custom(&$err)),
}
};
}
#[macro_export]
macro_rules! extract_str {
($value:expr, $err:expr) => {
match $value {
$crate::Value::Str { data, .. } => data.as_ref(),
_ => return Err($crate::Error::custom(&$err)),
}
};
}
#[macro_export]
macro_rules! pop_or_fail {
($context:expr, $err:expr) => {
match $context.pstack.pop() {
Some(v) => v,
None => return $context.fail(&$err),
}
};
}
#[macro_export]
macro_rules! peek_or_fail {
($context:expr, $err:expr) => {
match $context.pstack.top() {
Some(v) => v,
None => return $context.fail(&$err),
}
};
}
#[macro_export]
macro_rules! register_api_func {
($linker:expr, $engine:expr, $module:expr, $name:expr, $func:expr) => {
$linker
.func_new(
$module,
$name,
wasmtime::FuncType::new(
$engine,
[wasmtime::ValType::I32, wasmtime::ValType::I32],
[wasmtime::ValType::I32],
),
$func,
)
.map_err(|e| $crate::error::ApiError::RegisterApiFailed {
function_name: $name.to_string(),
reason: format!("{}", e),
})?
};
}
#[cfg(test)]
mod tests {
use crate::Value;
#[test]
fn test_extract_bin_macro() {
fn extract(value: &Value) -> Result<usize, crate::Error> {
let data = match value {
Value::Bin { data, .. } => data.as_ref(),
_ => return Err(crate::Error::custom(&"expected binary")),
};
Ok(data.len())
}
let value: Value = vec![1, 2, 3].into();
assert_eq!(extract(&value).unwrap(), 3);
let value: Value = "wrong type".into();
assert!(extract(&value).is_err());
}
#[test]
fn test_extract_str_macro() {
fn extract(value: &Value) -> Result<usize, crate::Error> {
let data = match value {
Value::Str { data, .. } => data.as_ref(),
_ => return Err(crate::Error::custom(&"expected string")),
};
Ok(data.len())
}
let value: Value = "hello".into();
assert_eq!(extract(&value).unwrap(), 5);
let value: Value = vec![1, 2, 3].into();
assert!(extract(&value).is_err());
}
}