Skip to content

Commit

Permalink
move to chain.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
parkma99 committed Oct 29, 2024
1 parent 37127c4 commit 010b7f5
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 122 deletions.
127 changes: 127 additions & 0 deletions rama-dns/src/chain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use std::net::{Ipv4Addr, Ipv6Addr};

use rama_net::address::Domain;

use crate::DnsResolver;

#[derive(Debug)]
pub struct DnsChainDomainResolveErr<E: 'static> {
errors: Vec<E>,
}

impl<E: std::fmt::Debug> std::fmt::Display for DnsChainDomainResolveErr<E> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"domain resolver chain resulted in errors: {:?}",
self.errors
)
}
}

impl<E: std::error::Error + 'static> std::error::Error for DnsChainDomainResolveErr<E> {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.errors.last()
}
}

macro_rules! dns_resolver_chain_impl {
() => {
async fn ipv4_lookup(&self, domain: Domain) -> Result<Vec<Ipv4Addr>, Self::Error> {
let mut errors = Vec::new();
for resolver in self {
match resolver.ipv4_lookup(domain.clone()).await {
Ok(ipv4s) => return Ok(ipv4s),
Err(err) => errors.push(err),
}
}
Err(DnsChainDomainResolveErr { errors })
}

async fn ipv6_lookup(&self, domain: Domain) -> Result<Vec<Ipv6Addr>, Self::Error> {
let mut errors = Vec::new();
for resolver in self {
match resolver.ipv6_lookup(domain.clone()).await {
Ok(ipv6s) => return Ok(ipv6s),
Err(err) => errors.push(err),
}
}
Err(DnsChainDomainResolveErr { errors })
}
};
}

impl<R, E> DnsResolver for Vec<R>
where
R: DnsResolver<Error = E> + Send,
E: Send + 'static,
{
type Error = DnsChainDomainResolveErr<E>;

dns_resolver_chain_impl!();
}

impl<R, E, const N: usize> DnsResolver for [R; N]
where
R: DnsResolver<Error = E> + Send,
E: Send + 'static,
{
type Error = DnsChainDomainResolveErr<E>;
dns_resolver_chain_impl!();
}

#[cfg(test)]
mod tests {
use crate::{DenyAllDns, DnsOverwrite, InMemoryDns};
use rama_core::combinators::Either;
use std::net::{Ipv4Addr, Ipv6Addr};

use super::*;

#[tokio::test]
async fn test_empty_chain_vec() {
let v = Vec::<InMemoryDns>::new();
assert!(v
.ipv4_lookup(Domain::from_static("plabayo.tech"))
.await
.is_err());
assert!(v
.ipv6_lookup(Domain::from_static("plabayo.tech"))
.await
.is_err());
}

#[tokio::test]
async fn test_empty_chain_array() {
let a: [InMemoryDns; 0] = [];
assert!(a
.ipv4_lookup(Domain::from_static("plabayo.tech"))
.await
.is_err());
assert!(a
.ipv6_lookup(Domain::from_static("plabayo.tech"))
.await
.is_err());
}

// #[tokio::test]
// async fn test_chain_ok_err_ipv4() {
// let v: Vec<Either<_, DenyAllDns>> = vec![
// Either::A(serde_html_form::from_str("example.com=127.0.0.1").unwrap()),
// Either::B(DenyAllDns::new()),
// ];
// assert_eq!(
// v.ipv4_lookup(Domain::from_static("example.com"))
// .await
// .unwrap()
// .into_iter()
// .next()
// .unwrap(),
// Ipv4Addr::new(127, 0, 0, 1)
// );
// assert!(v
// .ipv6_lookup(Domain::from_static("example.com"))
// .await
// .is_err());
// }
}
126 changes: 4 additions & 122 deletions rama-dns/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,128 +79,6 @@ impl<R: DnsResolver<Error: Into<BoxError>>> DnsResolver for Option<R> {
}
}

#[derive(Debug)]
pub struct DnsChainDomainResolveErr<E: 'static> {
errors: Vec<E>,
}

impl<E: std::fmt::Debug> std::fmt::Display for DnsChainDomainResolveErr<E> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"domain resolver chain resulted in errors: {:?}",
self.errors
)
}
}

impl<E: std::fmt::Debug + Send + std::error::Error> std::error::Error
for DnsChainDomainResolveErr<E>
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.errors.last().map(|e| e as &dyn std::error::Error)
}
}

impl<R, E> DnsResolver for Vec<R>
where
R: DnsResolver<Error = E> + Send,
E: Send + 'static,
{
type Error = DnsChainDomainResolveErr<E>;

async fn ipv4_lookup(&self, domain: Domain) -> Result<Vec<Ipv4Addr>, Self::Error> {
let mut errors = Vec::new();
for resolver in self {
match resolver.ipv4_lookup(domain.clone()).await {
Ok(ipv4s) => return Ok(ipv4s),
Err(err) => errors.push(err),
}
}
Err(DnsChainDomainResolveErr { errors })
}

async fn ipv6_lookup(&self, domain: Domain) -> Result<Vec<Ipv6Addr>, Self::Error> {
let mut errors = Vec::new();
for resolver in self {
match resolver.ipv6_lookup(domain.clone()).await {
Ok(ipv6s) => return Ok(ipv6s),
Err(err) => errors.push(err),
}
}
Err(DnsChainDomainResolveErr { errors })
}
}

impl<R, E, const N: usize> DnsResolver for [R; N]
where
R: DnsResolver<Error = E> + Send,
E: Send + 'static,
{
type Error = DnsChainDomainResolveErr<E>;

async fn ipv4_lookup(&self, domain: Domain) -> Result<Vec<Ipv4Addr>, Self::Error> {
let mut errors = Vec::new();
for resolver in self {
match resolver.ipv4_lookup(domain.clone()).await {
Ok(ipv4s) => return Ok(ipv4s),
Err(err) => errors.push(err),
}
}
Err(DnsChainDomainResolveErr { errors })
}

async fn ipv6_lookup(&self, domain: Domain) -> Result<Vec<Ipv6Addr>, Self::Error> {
let mut errors = Vec::new();
for resolver in self {
match resolver.ipv6_lookup(domain.clone()).await {
Ok(ipv6s) => return Ok(ipv6s),
Err(err) => errors.push(err),
}
}
Err(DnsChainDomainResolveErr { errors })
}
}

macro_rules! impl_dns_resolver_either_either {
($id:ident, $($param:ident),+ $(,)?) => {
impl<$($param),+> DnsResolver for ::rama_core::combinators::$id<$($param),+>
where
$($param: DnsResolver<Error: Into<::rama_core::error::BoxError>>),+,
{
type Error = ::rama_core::error::BoxError;

async fn ipv4_lookup(
&self,
domain: Domain,
) -> Result<Vec<Ipv4Addr>, Self::Error>{
match self {
$(
::rama_core::combinators::$id::$param(d) => d.ipv4_lookup(domain)
.await
.map_err(Into::into),
)+
}
}

async fn ipv6_lookup(
&self,
domain: Domain,
) -> Result<Vec<Ipv6Addr>, Self::Error> {
match self {
$(
::rama_core::combinators::$id::$param(d) => d.ipv6_lookup(domain)
.await
.map_err(Into::into),
)+
}
}
}
};
}

rama_core::combinators::impl_either!(impl_dns_resolver_either_either);

pub mod hickory;
#[doc(inline)]
pub use hickory::HickoryDns;
Expand All @@ -212,3 +90,7 @@ pub use in_memory::{DnsOverwrite, DomainNotMappedErr, InMemoryDns};
mod deny_all;
#[doc(inline)]
pub use deny_all::{DenyAllDns, DnsDeniedError};

pub mod chain;

pub mod variant;
41 changes: 41 additions & 0 deletions rama-dns/src/variant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::DnsResolver;
use rama_net::address::Domain;
use std::net::{Ipv4Addr, Ipv6Addr};
macro_rules! impl_dns_resolver_either_either {
($id:ident, $($param:ident),+ $(,)?) => {
impl<$($param),+> DnsResolver for ::rama_core::combinators::$id<$($param),+>
where
$($param: DnsResolver<Error: Into<::rama_core::error::BoxError>>),+,
{
type Error = ::rama_core::error::BoxError;

async fn ipv4_lookup(
&self,
domain: Domain,
) -> Result<Vec<Ipv4Addr>, Self::Error>{
match self {
$(
::rama_core::combinators::$id::$param(d) => d.ipv4_lookup(domain)
.await
.map_err(Into::into),
)+
}
}

async fn ipv6_lookup(
&self,
domain: Domain,
) -> Result<Vec<Ipv6Addr>, Self::Error> {
match self {
$(
::rama_core::combinators::$id::$param(d) => d.ipv6_lookup(domain)
.await
.map_err(Into::into),
)+
}
}
}
};
}

rama_core::combinators::impl_either!(impl_dns_resolver_either_either);

0 comments on commit 010b7f5

Please sign in to comment.