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::future::Future;
51 use std::net::{Ipv4Addr, Ipv6Addr};
52
53 struct MockResolver1;
55 struct MockResolver2;
56
57 impl DnsResolver for MockResolver1 {
58 type Error = BoxError;
59
60 fn ipv4_lookup(
61 &self,
62 _domain: Domain,
63 ) -> impl Future<Output = Result<Vec<Ipv4Addr>, Self::Error>> {
64 std::future::ready(Ok(vec![Ipv4Addr::new(127, 0, 0, 1)]))
65 }
66
67 fn ipv6_lookup(
68 &self,
69 _domain: Domain,
70 ) -> impl Future<Output = Result<Vec<Ipv6Addr>, Self::Error>> {
71 std::future::ready(Ok(vec![Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)]))
72 }
73 }
74
75 impl DnsResolver for MockResolver2 {
76 type Error = BoxError;
77
78 fn ipv4_lookup(
79 &self,
80 _domain: Domain,
81 ) -> impl Future<Output = Result<Vec<Ipv4Addr>, Self::Error>> + Send + '_ {
82 std::future::ready(Ok(vec![Ipv4Addr::new(192, 168, 1, 1)]))
83 }
84
85 fn ipv6_lookup(
86 &self,
87 _domain: Domain,
88 ) -> impl Future<Output = Result<Vec<Ipv6Addr>, Self::Error>> + Send + '_ {
89 std::future::ready(Ok(vec![Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 2)]))
90 }
91 }
92
93 #[tokio::test]
94 async fn test_either_ipv4_lookup() {
95 let resolver1 = Either::<MockResolver1, MockResolver2>::A(MockResolver1);
96 let resolver2 = Either::<MockResolver1, MockResolver2>::B(MockResolver2);
97
98 let domain = "example.com".parse::<Domain>().unwrap();
99
100 let result1 = resolver1.ipv4_lookup(domain.clone()).await.unwrap();
101 assert_eq!(result1, vec![Ipv4Addr::new(127, 0, 0, 1)]);
102
103 let result2 = resolver2.ipv4_lookup(domain).await.unwrap();
104 assert_eq!(result2, vec![Ipv4Addr::new(192, 168, 1, 1)]);
105 }
106
107 #[tokio::test]
108 async fn test_either_ipv6_lookup() {
109 let resolver1 = Either::<MockResolver1, MockResolver2>::A(MockResolver1);
110 let resolver2 = Either::<MockResolver1, MockResolver2>::B(MockResolver2);
111
112 let domain = "example.com".parse::<Domain>().unwrap();
113
114 let result1 = resolver1.ipv6_lookup(domain.clone()).await.unwrap();
115 assert_eq!(result1, vec![Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)]);
116
117 let result2 = resolver2.ipv6_lookup(domain).await.unwrap();
118 assert_eq!(result2, vec![Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 2)]);
119 }
120}