rsip-dns 0.1.4

SIP Rust library implementing RFC 3263, implemented on top of rsip
Documentation
use crate::{
    resolvables::{ResolvableExt, ResolvableIpAddr, ResolvableState, ResolvableVec},
    DnsClient, Target,
};
use async_trait::async_trait;
use rsip::{Domain, Port, Transport};

#[derive(Debug, Clone)]
pub struct ResolvableAddrRecord<C>
where
    C: DnsClient,
{
    dns_client: C,
    domain: Domain,
    port: Port,
    transport: Transport,
    resolvable_ip_addrs: ResolvableVec<ResolvableIpAddr, Target>,
}

#[async_trait]
impl<C> ResolvableExt<Target> for ResolvableAddrRecord<C>
where
    C: DnsClient,
{
    fn state(&self) -> ResolvableState {
        self.resolvable_ip_addrs.state()
    }

    async fn resolve_next(&mut self) -> Option<Target> {
        if self.resolvable_ip_addrs.is_unset() {
            self.resolve_domain().await;
        }

        self.resolvable_ip_addrs.resolve_next().await
    }
}

impl<C> ResolvableAddrRecord<C>
where
    C: DnsClient,
{
    pub fn new(dns_client: C, domain: Domain, port: Port, transport: Transport) -> Self {
        Self { dns_client, domain, port, transport, resolvable_ip_addrs: Default::default() }
    }

    async fn resolve_domain(&mut self) {
        match self.dns_client.ip_lookup(self.domain.clone()).await {
            Ok(a_record) => {
                let resolvable_ip_addrs = a_record
                    .ip_addrs
                    .into_iter()
                    .map(|ip_addr| ResolvableIpAddr::new(ip_addr, self.port, self.transport))
                    .collect::<Vec<_>>();
                self.resolvable_ip_addrs = ResolvableVec::non_empty(resolvable_ip_addrs)
            }
            Err(_) => {
                self.resolvable_ip_addrs = ResolvableVec::empty();
            }
        }
    }
}