macro_rules! ares_call {
(
$ares_call:ident,
$channel:expr,
$name:expr,
$dns_class:expr,
$query_type:expr,
$callback:expr,
$handler:expr
) => {{
let Ok(c_name) = CString::new($name) else {
$handler(Err(Error::EBADNAME));
return;
};
let c_arg = Box::into_raw(Box::new($handler));
unsafe {
c_ares_sys::$ares_call(
$channel,
c_name.as_ptr(),
$dns_class as c_int,
$query_type as c_int,
Some($callback),
c_arg.cast(),
);
}
}};
}
macro_rules! ares_query {
($($arg:tt)*) => { ares_call!(ares_query, $($arg)*) }
}
macro_rules! ares_search {
($($arg:tt)*) => { ares_call!(ares_search, $($arg)*) }
}
macro_rules! ares_callback {
($arg:expr, $status:expr, $abuf:expr, $alen:expr, $parser:expr) => {{
let result = if $status == c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
debug_assert!(
$alen >= 0,
"ares_callback received negative alen on success"
);
let data = unsafe { slice::from_raw_parts($abuf, $alen as usize) };
$parser(data)
} else {
Err(Error::from($status))
};
let handler = unsafe { Box::from_raw($arg) };
panic::abort_on_panic(|| handler(result));
}};
}