1use std::fmt;
2use std::os::raw::{c_int, c_void};
3
4use crate::error::{Error, Result};
5use crate::hostent::{HasHostent, HostAddressResultsIter, HostAliasResultsIter, HostentBorrowed};
6use crate::panic;
7
8#[derive(Clone, Copy)]
10pub struct HostResults<'a> {
11 hostent: HostentBorrowed<'a>,
12}
13
14impl<'a> HostResults<'a> {
15 fn new(hostent: &'a c_types::hostent) -> Self {
16 HostResults {
17 hostent: HostentBorrowed::new(hostent),
18 }
19 }
20
21 pub fn hostname(self) -> &'a str {
23 self.hostent.hostname()
24 }
25
26 pub fn addresses(self) -> HostAddressResultsIter<'a> {
28 self.hostent.addresses()
29 }
30
31 pub fn aliases(self) -> HostAliasResultsIter<'a> {
33 self.hostent.aliases()
34 }
35}
36
37impl fmt::Display for HostResults<'_> {
38 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
39 self.hostent.fmt(fmt)
40 }
41}
42
43pub(crate) unsafe extern "C" fn get_host_callback<F>(
44 arg: *mut c_void,
45 status: c_int,
46 _timeouts: c_int,
47 hostent: *mut c_types::hostent,
48) where
49 F: FnOnce(Result<HostResults>) + Send + 'static,
50{
51 panic::catch(|| {
52 let result = if status == c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
53 let host_results = HostResults::new(unsafe { &*hostent });
54 Ok(host_results)
55 } else {
56 Err(Error::from(status))
57 };
58 let handler = unsafe { Box::from_raw(arg.cast::<F>()) };
59 handler(result);
60 });
61}