rsip-dns 0.1.4

SIP Rust library implementing RFC 3263, implemented on top of rsip
Documentation
use crate::{
    records::SrvDomain,
    resolvables::{ResolvableAddrRecord, ResolvableExt, ResolvableState, ResolvableVec},
    DnsClient, Target,
};
use async_trait::async_trait;

#[derive(Debug, Clone)]
pub struct ResolvableSrvRecord<C>
where
    C: DnsClient,
{
    dns_client: C,
    domain: SrvDomain,
    resolvable_addr_records: ResolvableVec<ResolvableAddrRecord<C>, Target>,
}

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

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

        self.resolvable_addr_records.resolve_next().await
    }
}

impl<C> ResolvableSrvRecord<C>
where
    C: DnsClient,
{
    pub fn new(dns_client: C, domain: SrvDomain) -> Self {
        Self { dns_client, domain, resolvable_addr_records: Default::default() }
    }

    async fn resolve_domain(&mut self) {
        match self.dns_client.srv_lookup(self.domain.clone()).await {
            Some(srv_record) => {
                let resolvable_addr_records = srv_record
                    .domains_with_ports()
                    .into_iter()
                    .map(|(domain, port)| {
                        ResolvableAddrRecord::new(
                            self.dns_client.clone(),
                            domain,
                            port,
                            srv_record.transport(),
                        )
                    })
                    .collect::<Vec<_>>();

                self.resolvable_addr_records = ResolvableVec::non_empty(resolvable_addr_records)
            }
            None => {
                self.resolvable_addr_records = ResolvableVec::empty();
            }
        }
    }
}