use futures_io::{AsyncRead, AsyncWrite}; use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; use trust_dns_resolver::config::{ResolverConfig, ResolverOpts}; pub fn resolver( config: ResolverConfig, options: ResolverOpts, ) -> Result { JiveResolver::new(config, options, JiveRuntimeHandle) } pub fn resolver_from_system_conf() -> Result { JiveResolver::from_system_conf(JiveRuntimeHandle) } #[derive(Clone)] pub struct JiveRuntime; pub struct JiveTcpStream { pub(crate) io: jive::io::Async, } pub struct JiveUdpSocket { io: jive::io::Async, } pub type JiveResolver = trust_dns_resolver::AsyncResolver; pub type JiveConnection = trust_dns_resolver::name_server::GenericConnection; pub type JiveConnectionProvider = trust_dns_resolver::name_server::GenericConnectionProvider; #[derive(Clone, Copy)] pub struct JiveRuntimeHandle; pub struct JiveTimer; impl JiveTcpStream { pub fn into_inner(self) -> jive::io::Async { self.io } pub fn from_inner(io: jive::io::Async) -> Self { JiveTcpStream { io } } } impl trust_dns_resolver::name_server::RuntimeProvider for JiveRuntime { type Handle = JiveRuntimeHandle; type Tcp = JiveTcpStream; type Timer = JiveTimer; type Udp = JiveUdpSocket; } impl trust_dns_resolver::name_server::Spawn for JiveRuntimeHandle { fn spawn_bg(&mut self, future: F) where F: Future> + Send + 'static, { let _join = jive::spawn(future); } } #[async_trait::async_trait] impl trust_dns_proto::tcp::Connect for JiveTcpStream { async fn connect_with_bind( addr: std::net::SocketAddr, bind_addr: Option, ) -> std::io::Result { if let Some(_bind_addr) = bind_addr { todo!("Implement connect with bind"); } else { let io = jive::io::Async::::connect(addr).await?; Ok(JiveTcpStream { io }) } } } impl trust_dns_proto::tcp::DnsTcpStream for JiveTcpStream { type Time = JiveTimer; } impl AsyncRead for JiveTcpStream { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { Pin::new(&mut self.get_mut().io).poll_read(cx, buf) } } impl AsyncWrite for JiveTcpStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { Pin::new(&mut self.get_mut().io).poll_write(cx, buf) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut self.get_mut().io).poll_flush(cx) } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut self.get_mut().io).poll_close(cx) } } #[async_trait::async_trait] impl trust_dns_proto::udp::UdpSocket for JiveUdpSocket { type Time = JiveTimer; async fn bind(addr: std::net::SocketAddr) -> std::io::Result { let io = jive::io::Async::::bind(addr).await?; Ok(JiveUdpSocket { io }) } fn poll_send_to( &self, cx: &mut Context<'_>, buf: &[u8], target: std::net::SocketAddr, ) -> Poll> { self.io.poll_send_to(cx, buf, target) } fn poll_recv_from( &self, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { self.io.poll_recv_from(cx, buf) } } #[async_trait::async_trait] impl trust_dns_proto::Time for JiveTimer { async fn delay_for(duration: std::time::Duration) { jive::time::sleep(duration).await } async fn timeout( duration: std::time::Duration, future: F, ) -> Result { jive::time::timeout(duration, Box::pin(future)).await } } impl trust_dns_proto::Executor for JiveRuntime { fn new() -> Self { Self } fn block_on(&mut self, future: F) -> F::Output { jive::block_on(future) } }