#[macro_export]
macro_rules! ffi_error {
($err:expr) => {{
let err_code = $crate::ffi_error_code!($err);
let err_desc = $err.to_string();
(err_code, err_desc)
}};
}
#[macro_export]
macro_rules! ffi_result {
($res:expr) => {
match $res {
Ok(_) => (0, String::default()),
Err(error) => $crate::ffi_error!(error),
}
};
}
#[macro_export]
macro_rules! ffi_result_code {
($res:expr) => {
match $res {
Ok(_) => 0,
Err(error) => $crate::ffi_error_code!(error),
}
};
}
#[macro_export]
macro_rules! ffi_error_code {
($err:expr) => {{
#[allow(unused, clippy::useless_attribute)]
use $crate::ErrorCode;
let err = &$err;
let err_str = format!("{:?}", err);
let err_code = err.error_code();
log::debug!("**ERRNO: {}** {}", err_code, err_str);
err_code
}};
}
#[macro_export]
macro_rules! call_result_cb {
($result:expr, $user_data:expr, $cb:expr) => {
#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
#[allow(unused)]
use $crate::callback::{Callback, CallbackArgs};
use $crate::result::{FfiResult, NativeResult};
let (error_code, description) = $crate::ffi_result!($result);
let res = NativeResult {
error_code,
description: Some(description),
}
.into_repr_c();
match res {
Ok(res) => $cb.call($user_data.into(), &res, CallbackArgs::default()),
Err(_) => {
let res = FfiResult {
error_code,
description: b"Could not convert error description into CString\x00"
as *const u8 as *const _,
};
$cb.call($user_data.into(), &res, CallbackArgs::default());
}
}
};
}
#[macro_export]
macro_rules! try_cb {
($result:expr, $user_data:expr, $cb:expr) => {
match $result {
Ok(value) => value,
e @ Err(_) => {
$crate::call_result_cb!(e, $user_data, $cb);
return None;
}
}
};
}
#[cfg(test)]
mod tests {
use crate::test_utils::TestError;
#[test]
fn error_code_and_desc() {
{
let err = TestError::Test;
let (code, desc) = ffi_error!(err);
assert_eq!(code, -1);
assert_eq!(desc, "Test Error");
}
{
let err = TestError::from("howdy");
let (code, desc) = ffi_error!(err);
assert_eq!(code, -2);
assert_eq!(desc, "howdy".to_string());
}
}
}