use std::ffi::CStr;
use std::fmt;
use std::os::raw::{c_int, c_uchar, c_void};
use std::ptr;
use std::slice;
use crate::error::{Error, Result};
use crate::hostent::{HasHostent, HostAliasResultsIter, HostentOwned};
use crate::panic;
#[derive(Debug)]
pub struct CNameResults {
hostent: HostentOwned,
}
impl CNameResults {
pub fn parse_from(data: &[u8]) -> Result<CNameResults> {
let mut hostent: *mut c_types::hostent = ptr::null_mut();
let parse_status = unsafe {
c_ares_sys::ares_parse_a_reply(
data.as_ptr(),
data.len() as c_int,
&mut hostent,
ptr::null_mut(),
ptr::null_mut(),
)
};
if parse_status == c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
let result = CNameResults::new(hostent);
Ok(result)
} else {
Err(Error::from(parse_status))
}
}
fn new(hostent: *mut c_types::hostent) -> Self {
CNameResults {
hostent: HostentOwned::new(hostent),
}
}
pub fn hostname(&self) -> &CStr {
self.hostent.hostname()
}
pub fn aliases(&self) -> HostAliasResultsIter {
self.hostent.aliases()
}
}
impl fmt::Display for CNameResults {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self.hostent.fmt(fmt)
}
}
pub(crate) unsafe extern "C" fn query_cname_callback<F>(
arg: *mut c_void,
status: c_int,
_timeouts: c_int,
abuf: *mut c_uchar,
alen: c_int,
) where
F: FnOnce(Result<CNameResults>) + Send + 'static,
{
ares_callback!(
arg.cast::<F>(),
status,
abuf,
alen,
CNameResults::parse_from
);
}