rama_dns/
variant.rs

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    // Mock DNS resolvers for testing
54    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}