1use crate::DnsResolver;
2use rama_net::address::Domain;
3use std::net::{Ipv4Addr, Ipv6Addr};
4
5macro_rules! impl_dns_resolver_either_either {
6 ($id:ident, $($param:ident),+ $(,)?) => {
7 impl<$($param),+> DnsResolver for ::rama_core::combinators::$id<$($param),+>
8 where
9 $($param: DnsResolver<Error: Into<::rama_core::error::BoxError>>),+,
10 {
11 type Error = ::rama_core::error::BoxError;
12
13 async fn ipv4_lookup(
14 &self,
15 domain: Domain,
16 ) -> Result<Vec<Ipv4Addr>, Self::Error>{
17 match self {
18 $(
19 ::rama_core::combinators::$id::$param(d) => d.ipv4_lookup(domain)
20 .await
21 .map_err(Into::into),
22 )+
23 }
24 }
25
26 async fn ipv6_lookup(
27 &self,
28 domain: Domain,
29 ) -> Result<Vec<Ipv6Addr>, Self::Error> {
30 match self {
31 $(
32 ::rama_core::combinators::$id::$param(d) => d.ipv6_lookup(domain)
33 .await
34 .map_err(Into::into),
35 )+
36 }
37 }
38 }
39 };
40}
41
42rama_core::combinators::impl_either!(impl_dns_resolver_either_either);
43
44#[cfg(test)]
45mod tests {
46 use crate::DnsResolver;
47 use rama_core::combinators::Either;
48 use rama_core::error::BoxError;
49 use rama_net::address::Domain;
50 use std::net::{Ipv4Addr, Ipv6Addr};
51
52 struct MockResolver1;
54 struct MockResolver2;
55
56 impl DnsResolver for MockResolver1 {
57 type Error = BoxError;
58
59 fn ipv4_lookup(
60 &self,
61 _domain: Domain,
62 ) -> impl Future<Output = Result<Vec<Ipv4Addr>, Self::Error>> {
63 std::future::ready(Ok(vec![Ipv4Addr::new(127, 0, 0, 1)]))
64 }
65
66 fn ipv6_lookup(
67 &self,
68 _domain: Domain,
69 ) -> impl Future<Output = Result<Vec<Ipv6Addr>, Self::Error>> {
70 std::future::ready(Ok(vec![Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)]))
71 }
72 }
73
74 impl DnsResolver for MockResolver2 {
75 type Error = BoxError;
76
77 fn ipv4_lookup(
78 &self,
79 _domain: Domain,
80 ) -> impl Future<Output = Result<Vec<Ipv4Addr>, Self::Error>> + Send + '_ {
81 std::future::ready(Ok(vec![Ipv4Addr::new(192, 168, 1, 1)]))
82 }
83
84 fn ipv6_lookup(
85 &self,
86 _domain: Domain,
87 ) -> impl Future<Output = Result<Vec<Ipv6Addr>, Self::Error>> + Send + '_ {
88 std::future::ready(Ok(vec![Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 2)]))
89 }
90 }
91
92 #[tokio::test]
93 async fn test_either_ipv4_lookup() {
94 let resolver1 = Either::<MockResolver1, MockResolver2>::A(MockResolver1);
95 let resolver2 = Either::<MockResolver1, MockResolver2>::B(MockResolver2);
96
97 let domain = "example.com".parse::<Domain>().unwrap();
98
99 let result1 = resolver1.ipv4_lookup(domain.clone()).await.unwrap();
100 assert_eq!(result1, vec![Ipv4Addr::new(127, 0, 0, 1)]);
101
102 let result2 = resolver2.ipv4_lookup(domain).await.unwrap();
103 assert_eq!(result2, vec![Ipv4Addr::new(192, 168, 1, 1)]);
104 }
105
106 #[tokio::test]
107 async fn test_either_ipv6_lookup() {
108 let resolver1 = Either::<MockResolver1, MockResolver2>::A(MockResolver1);
109 let resolver2 = Either::<MockResolver1, MockResolver2>::B(MockResolver2);
110
111 let domain = "example.com".parse::<Domain>().unwrap();
112
113 let result1 = resolver1.ipv6_lookup(domain.clone()).await.unwrap();
114 assert_eq!(result1, vec![Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)]);
115
116 let result2 = resolver2.ipv6_lookup(domain).await.unwrap();
117 assert_eq!(result2, vec![Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 2)]);
118 }
119}