hyper_system_resolver/
background.rs1use std::{
11 fmt,
12 future::Future,
13 io,
14 net::SocketAddr,
15 pin::Pin,
16 task::{self, Poll},
17};
18
19use hyper::client::connect::dns::Name;
20use tokio::task::JoinHandle;
21use tower_service::Service;
22
23pub trait Resolve {
25 type Iter: Iterator<Item = SocketAddr>;
27
28 fn resolve(&mut self, name: Name) -> JoinHandle<io::Result<Self::Iter>>;
30}
31
32#[derive(Clone)]
35pub struct Resolver<T> {
36 inner: T,
37}
38
39impl<T> Resolver<T> {
40 pub fn new(inner: T) -> Self {
42 Self { inner }
43 }
44
45 pub fn into_inner(self) -> T {
47 self.inner
48 }
49}
50
51impl<T> AsRef<T> for Resolver<T> {
52 fn as_ref(&self) -> &T {
53 &self.inner
54 }
55}
56
57impl<T> Service<Name> for Resolver<T>
58where
59 T: Resolve + Send + Sync + 'static,
60{
61 type Response = <T as Resolve>::Iter;
62 type Error = io::Error;
63 type Future = ResolverFuture<<T as Resolve>::Iter>;
64
65 fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), io::Error>> {
66 Poll::Ready(Ok(()))
67 }
68
69 fn call(&mut self, name: Name) -> Self::Future {
70 let handle = self.inner.resolve(name);
71 ResolverFuture { inner: handle }
72 }
73}
74
75impl<T> fmt::Debug for Resolver<T> {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 f.pad("Resolver")
78 }
79}
80
81pub struct ResolverFuture<T> {
86 inner: JoinHandle<io::Result<T>>,
87}
88
89impl<T> Future for ResolverFuture<T> {
90 type Output = io::Result<T>;
91
92 fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
93 Pin::new(&mut self.inner).poll(cx).map(|res| match res {
94 Ok(Ok(addrs)) => Ok(addrs),
95 Ok(Err(err)) => Err(err),
96 Err(join_err) => {
97 if join_err.is_cancelled() {
98 Err(io::Error::new(io::ErrorKind::Interrupted, join_err))
99 } else {
100 panic!("resolver Resolver task failed: {:?}", join_err)
101 }
102 }
103 })
104 }
105}
106
107impl<T> fmt::Debug for ResolverFuture<T> {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 f.pad("ResolverFuture")
110 }
111}