hyper_system_resolver/
addr_info_hints.rs

1//! [`AddrInfoHints`] and associated types.
2//!
3//! This is only required if you prefer a portable interface.
4//! You can use a raw [`dns_lookup::AddrInfoHints`] instead.
5
6use dns_lookup::AddrFamily;
7
8#[cfg(unix)]
9use libc::{AF_INET, AF_INET6, AF_UNIX, AF_UNSPEC};
10
11#[cfg(windows)]
12use winapi::shared::ws2def::{AF_INET, AF_INET6, AF_UNIX, AF_UNSPEC};
13
14/// The address family to request when resolving the name.
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum AddressFamily {
17    /// No preference.
18    Unspec,
19    /// Request UNIX-family address.
20    Unix,
21    /// Request IPv4-family address.
22    Inet,
23    /// Request IPv6-family address.
24    Inet6,
25    /// Request custom address family.
26    Custom(i32),
27}
28
29impl Default for AddressFamily {
30    fn default() -> Self {
31        Self::Unspec
32    }
33}
34
35impl From<AddrFamily> for AddressFamily {
36    fn from(af: AddrFamily) -> Self {
37        match af {
38            AddrFamily::Inet => Self::Inet,
39            AddrFamily::Inet6 => Self::Inet6,
40            AddrFamily::Unix => Self::Unix,
41        }
42    }
43}
44
45/// Portable [`AddrInfoHints`].
46#[derive(Debug, Default)]
47#[cfg_attr(feature = "builder", derive(derive_builder::Builder))]
48pub struct AddrInfoHints {
49    #[cfg_attr(feature = "builder", builder(default))]
50    /// Address family to request.
51    pub address_family: AddressFamily,
52}
53
54impl AddrInfoHints {
55    /// Create a new [`AddrInfoHints`] builder.
56    #[cfg(feature = "builder")]
57    pub fn builder() -> AddrInfoHintsBuilder {
58        AddrInfoHintsBuilder::default()
59    }
60}
61
62impl From<&AddrInfoHints> for dns_lookup::AddrInfoHints {
63    fn from(opts: &AddrInfoHints) -> Self {
64        let address = match opts.address_family {
65            AddressFamily::Unspec => AF_UNSPEC,
66            AddressFamily::Inet => AF_INET,
67            AddressFamily::Inet6 => AF_INET6,
68            AddressFamily::Unix => AF_UNIX,
69            AddressFamily::Custom(val) => val,
70        };
71        Self {
72            address,
73            ..Default::default()
74        }
75    }
76}
77
78impl From<AddrInfoHints> for dns_lookup::AddrInfoHints {
79    fn from(opts: AddrInfoHints) -> Self {
80        From::from(&opts)
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87
88    #[test]
89    fn address_family() {
90        let cases = vec![
91            (AddrInfoHints::default(), AF_UNSPEC),
92            (
93                AddrInfoHints {
94                    address_family: AddressFamily::Unspec,
95                },
96                AF_UNSPEC,
97            ),
98            (
99                AddrInfoHints {
100                    address_family: AddressFamily::Inet,
101                },
102                AF_INET,
103            ),
104            (
105                AddrInfoHints {
106                    address_family: AddressFamily::Inet6,
107                },
108                AF_INET6,
109            ),
110            (
111                AddrInfoHints {
112                    address_family: AddressFamily::Unix,
113                },
114                AF_UNIX,
115            ),
116            (
117                AddrInfoHints {
118                    address_family: AddressFamily::Custom(123),
119                },
120                123,
121            ),
122        ];
123
124        for (addr_info_hints, expected) in cases {
125            let dns_lookup::AddrInfoHints { address, .. } = addr_info_hints.into();
126            assert_eq!(address, expected);
127        }
128    }
129}