1use std::fmt;
2use std::os::raw::{c_int, c_uchar, c_void};
3use std::ptr;
4use std::slice;
5
6use crate::error::{Error, Result};
7use crate::hostent::{HasHostent, HostAliasResultsIter, HostentOwned};
8use crate::panic;
9
10#[derive(Debug)]
12pub struct CNameResults {
13 hostent: HostentOwned,
14}
15
16impl CNameResults {
17 pub fn parse_from(data: &[u8]) -> Result<CNameResults> {
19 let mut hostent: *mut c_types::hostent = ptr::null_mut();
20 let parse_status = unsafe {
21 c_ares_sys::ares_parse_a_reply(
22 data.as_ptr(),
23 data.len() as c_int,
24 &mut hostent,
25 ptr::null_mut(),
26 ptr::null_mut(),
27 )
28 };
29 if parse_status == c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
30 let result = CNameResults::new(hostent);
31 Ok(result)
32 } else {
33 Err(Error::from(parse_status))
34 }
35 }
36
37 fn new(hostent: *mut c_types::hostent) -> Self {
38 CNameResults {
39 hostent: HostentOwned::new(hostent),
40 }
41 }
42
43 pub fn hostname(&self) -> &str {
45 self.hostent.hostname()
46 }
47
48 pub fn aliases(&self) -> HostAliasResultsIter {
50 self.hostent.aliases()
51 }
52}
53
54impl fmt::Display for CNameResults {
55 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
56 self.hostent.fmt(fmt)
57 }
58}
59
60pub(crate) unsafe extern "C" fn query_cname_callback<F>(
61 arg: *mut c_void,
62 status: c_int,
63 _timeouts: c_int,
64 abuf: *mut c_uchar,
65 alen: c_int,
66) where
67 F: FnOnce(Result<CNameResults>) + Send + 'static,
68{
69 ares_callback!(
70 arg.cast::<F>(),
71 status,
72 abuf,
73 alen,
74 CNameResults::parse_from
75 );
76}