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, Builder, Default)]
47pub struct AddrInfoHints {
48    #[builder(default)]
49    /// Address family to request.
50    pub address_family: AddressFamily,
51}
52
53impl AddrInfoHints {
54    /// Create a new [`AddrInfoHints`] builder.
55    pub fn builder() -> AddrInfoHintsBuilder {
56        AddrInfoHintsBuilder::default()
57    }
58}
59
60impl From<&AddrInfoHints> for dns_lookup::AddrInfoHints {
61    fn from(opts: &AddrInfoHints) -> Self {
62        let address = match opts.address_family {
63            AddressFamily::Unspec => AF_UNSPEC,
64            AddressFamily::Inet => AF_INET,
65            AddressFamily::Inet6 => AF_INET6,
66            AddressFamily::Unix => AF_UNIX,
67            AddressFamily::Custom(val) => val,
68        };
69        Self {
70            address,
71            ..Default::default()
72        }
73    }
74}
75
76impl From<AddrInfoHints> for dns_lookup::AddrInfoHints {
77    fn from(opts: AddrInfoHints) -> Self {
78        From::from(&opts)
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn address_family() {
88        let cases = vec![
89            (AddrInfoHints::default(), AF_UNSPEC),
90            (
91                AddrInfoHints {
92                    address_family: AddressFamily::Unspec,
93                },
94                AF_UNSPEC,
95            ),
96            (
97                AddrInfoHints {
98                    address_family: AddressFamily::Inet,
99                },
100                AF_INET,
101            ),
102            (
103                AddrInfoHints {
104                    address_family: AddressFamily::Inet6,
105                },
106                AF_INET6,
107            ),
108            (
109                AddrInfoHints {
110                    address_family: AddressFamily::Unix,
111                },
112                AF_UNIX,
113            ),
114            (
115                AddrInfoHints {
116                    address_family: AddressFamily::Custom(123),
117                },
118                123,
119            ),
120        ];
121
122        for (addr_info_hints, expected) in cases {
123            let dns_lookup::AddrInfoHints { address, .. } = addr_info_hints.into();
124            assert_eq!(address, expected);
125        }
126    }
127}