use core::future::Future;
use core::pin::Pin;
use std::sync::Arc;
use futures_util::stream::Stream;
use super::Client;
use crate::dnssec::DnssecDnsHandle;
use crate::error::NetError;
use crate::proto::dnssec::TrustAnchors;
use crate::proto::op::{DnsRequest, DnsResponse};
use crate::runtime::{TokioRuntimeProvider, TokioTime};
use crate::xfer::{DnsExchangeBackground, DnsHandle, DnsRequestSender};
pub struct DnssecClient {
client: DnssecDnsHandle<Client<TokioRuntimeProvider>>,
}
impl DnssecClient {
pub fn builder<F, S>(connect_future: F) -> AsyncSecureClientBuilder<F>
where
F: Future<Output = Result<S, NetError>> + 'static + Send + Unpin,
S: DnsRequestSender,
{
AsyncSecureClientBuilder {
connect_future,
trust_anchor: None,
}
}
pub async fn connect<F, S>(
connect_future: F,
) -> Result<(Self, DnsExchangeBackground<S, TokioTime>), NetError>
where
S: DnsRequestSender,
F: Future<Output = Result<S, NetError>> + 'static + Send + Unpin,
{
Self::builder(connect_future).build().await
}
pub fn from_client(
client: Client<TokioRuntimeProvider>,
trust_anchor: Arc<TrustAnchors>,
) -> Self {
Self {
client: DnssecDnsHandle::with_trust_anchor(client, trust_anchor),
}
}
}
impl Clone for DnssecClient {
fn clone(&self) -> Self {
Self {
client: self.client.clone(),
}
}
}
impl DnsHandle for DnssecClient {
type Response = Pin<Box<dyn Stream<Item = Result<DnsResponse, NetError>> + Send + 'static>>;
type Runtime = TokioRuntimeProvider;
fn send(&self, request: DnsRequest) -> Self::Response {
self.client.send(request)
}
}
pub struct AsyncSecureClientBuilder<F> {
connect_future: F,
trust_anchor: Option<TrustAnchors>,
}
impl<F, S> AsyncSecureClientBuilder<F>
where
F: Future<Output = Result<S, NetError>> + 'static + Send + Unpin,
S: DnsRequestSender,
{
pub fn trust_anchor(mut self, trust_anchor: TrustAnchors) -> Self {
self.trust_anchor = Some(trust_anchor);
self
}
pub async fn build(
mut self,
) -> Result<(DnssecClient, DnsExchangeBackground<S, TokioTime>), NetError> {
let trust_anchor = Arc::new(self.trust_anchor.take().unwrap_or_default());
let (client, bg) = Client::from_sender(self.connect_future.await?);
Ok((DnssecClient::from_client(client, trust_anchor), bg))
}
}