1- use std:: marker :: PhantomData ;
1+ use std:: mem ;
22use std:: net:: { IpAddr , Ipv4Addr , Ipv6Addr } ;
33use std:: net:: { SocketAddr , SocketAddrV4 , SocketAddrV6 } ;
44use std:: pin:: Pin ;
@@ -12,24 +12,37 @@ use crate::task::{blocking, Context, JoinHandle, Poll};
1212cfg_if ! {
1313 if #[ cfg( feature = "docs" ) ] {
1414 #[ doc( hidden) ]
15- pub struct ImplFuture <' a , T >( std:: marker:: PhantomData <& ' a T >) ;
15+ pub struct ImplFuture <T >( std:: marker:: PhantomData <T >) ;
1616
1717 macro_rules! ret {
18- ( $a : lifetime , $f : tt , $i : ty) => ( ImplFuture <$a , io :: Result <$i> >) ;
18+ ( impl Future < Output = $out : ty> , $fut : ty) => ( ImplFuture <$out >) ;
1919 }
2020 } else {
2121 macro_rules! ret {
22- ( $a : lifetime , $f : tt , $i : ty) => ( $f<$a , $i> ) ;
22+ ( impl Future < Output = $out : ty> , $fut : ty) => ( $fut ) ;
2323 }
2424 }
2525}
2626
27- /// A trait for objects which can be converted or resolved to one or more [`SocketAddr`] values.
27+ /// Converts or resolves addresses to [`SocketAddr`] values.
2828///
2929/// This trait is an async version of [`std::net::ToSocketAddrs`].
3030///
3131/// [`std::net::ToSocketAddrs`]: https://doc.rust-lang.org/std/net/trait.ToSocketAddrs.html
32- /// [`SocketAddr`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html
32+ /// [`SocketAddr`]: enum.SocketAddr.html
33+ ///
34+ /// # Examples
35+ ///
36+ /// ```
37+ /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
38+ /// #
39+ /// use async_std::net::ToSocketAddrs;
40+ ///
41+ /// let addr = "localhost:8080".to_socket_addrs().await?.next().unwrap();
42+ /// println!("resolved: {:?}", addr);
43+ /// #
44+ /// # Ok(()) }) }
45+ /// ```
3346pub trait ToSocketAddrs {
3447 /// Returned iterator over socket addresses which this type may correspond to.
3548 type Iter : Iterator < Item = SocketAddr > ;
@@ -40,124 +53,211 @@ pub trait ToSocketAddrs {
4053 /// resolution performed.
4154 ///
4255 /// Note that this function may block a backend thread while resolution is performed.
43- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) ;
56+ fn to_socket_addrs (
57+ & self ,
58+ ) -> ret ! (
59+ impl Future <Output = Self :: Iter >,
60+ ToSocketAddrsFuture <Self :: Iter >
61+ ) ;
4462}
4563
4664#[ doc( hidden) ]
4765#[ allow( missing_debug_implementations) ]
48- pub enum ToSocketAddrsFuture < ' a , I > {
49- Phantom ( PhantomData < & ' a ( ) > ) ,
50- Join ( JoinHandle < io:: Result < I > > ) ,
51- Ready ( Option < io :: Result < I > > ) ,
66+ pub enum ToSocketAddrsFuture < I > {
67+ Resolving ( JoinHandle < io :: Result < I > > ) ,
68+ Ready ( io:: Result < I > ) ,
69+ Done ,
5270}
5371
54- impl < I : Iterator < Item = SocketAddr > > Future for ToSocketAddrsFuture < ' _ , I > {
72+ impl < I : Iterator < Item = SocketAddr > > Future for ToSocketAddrsFuture < I > {
5573 type Output = io:: Result < I > ;
5674
5775 fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
58- match unsafe { self . get_unchecked_mut ( ) } {
59- ToSocketAddrsFuture :: Join ( f) => Pin :: new ( & mut * f) . poll ( cx) ,
60- ToSocketAddrsFuture :: Ready ( res) => {
61- let res = res. take ( ) . expect ( "polled a completed future" ) ;
62- Poll :: Ready ( res)
76+ let this = unsafe { self . get_unchecked_mut ( ) } ;
77+ let state = mem:: replace ( this, ToSocketAddrsFuture :: Done ) ;
78+
79+ match state {
80+ ToSocketAddrsFuture :: Resolving ( mut task) => {
81+ let poll = Pin :: new ( & mut task) . poll ( cx) ;
82+ if poll. is_pending ( ) {
83+ * this = ToSocketAddrsFuture :: Resolving ( task) ;
84+ }
85+ poll
6386 }
64- _ => unreachable ! ( ) ,
87+ ToSocketAddrsFuture :: Ready ( res) => Poll :: Ready ( res) ,
88+ ToSocketAddrsFuture :: Done => panic ! ( "polled a completed future" ) ,
6589 }
6690 }
6791}
6892
6993impl ToSocketAddrs for SocketAddr {
7094 type Iter = std:: option:: IntoIter < SocketAddr > ;
7195
72- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
73- ToSocketAddrsFuture :: Ready ( Some ( std:: net:: ToSocketAddrs :: to_socket_addrs ( self ) ) )
96+ fn to_socket_addrs (
97+ & self ,
98+ ) -> ret ! (
99+ impl Future <Output = Self :: Iter >,
100+ ToSocketAddrsFuture <Self :: Iter >
101+ ) {
102+ ToSocketAddrsFuture :: Ready ( Ok ( Some ( * self ) . into_iter ( ) ) )
74103 }
75104}
76105
77106impl ToSocketAddrs for SocketAddrV4 {
78107 type Iter = std:: option:: IntoIter < SocketAddr > ;
79108
80- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
81- ToSocketAddrsFuture :: Ready ( Some ( std:: net:: ToSocketAddrs :: to_socket_addrs ( self ) ) )
109+ fn to_socket_addrs (
110+ & self ,
111+ ) -> ret ! (
112+ impl Future <Output = Self :: Iter >,
113+ ToSocketAddrsFuture <Self :: Iter >
114+ ) {
115+ SocketAddr :: V4 ( * self ) . to_socket_addrs ( )
82116 }
83117}
84118
85119impl ToSocketAddrs for SocketAddrV6 {
86120 type Iter = std:: option:: IntoIter < SocketAddr > ;
87121
88- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
89- ToSocketAddrsFuture :: Ready ( Some ( std:: net:: ToSocketAddrs :: to_socket_addrs ( self ) ) )
122+ fn to_socket_addrs (
123+ & self ,
124+ ) -> ret ! (
125+ impl Future <Output = Self :: Iter >,
126+ ToSocketAddrsFuture <Self :: Iter >
127+ ) {
128+ SocketAddr :: V6 ( * self ) . to_socket_addrs ( )
90129 }
91130}
92131
93132impl ToSocketAddrs for ( IpAddr , u16 ) {
94133 type Iter = std:: option:: IntoIter < SocketAddr > ;
95134
96- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
97- ToSocketAddrsFuture :: Ready ( Some ( std:: net:: ToSocketAddrs :: to_socket_addrs ( self ) ) )
135+ fn to_socket_addrs (
136+ & self ,
137+ ) -> ret ! (
138+ impl Future <Output = Self :: Iter >,
139+ ToSocketAddrsFuture <Self :: Iter >
140+ ) {
141+ let ( ip, port) = * self ;
142+ match ip {
143+ IpAddr :: V4 ( a) => ( a, port) . to_socket_addrs ( ) ,
144+ IpAddr :: V6 ( a) => ( a, port) . to_socket_addrs ( ) ,
145+ }
98146 }
99147}
100148
101149impl ToSocketAddrs for ( Ipv4Addr , u16 ) {
102150 type Iter = std:: option:: IntoIter < SocketAddr > ;
103151
104- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
105- ToSocketAddrsFuture :: Ready ( Some ( std:: net:: ToSocketAddrs :: to_socket_addrs ( self ) ) )
152+ fn to_socket_addrs (
153+ & self ,
154+ ) -> ret ! (
155+ impl Future <Output = Self :: Iter >,
156+ ToSocketAddrsFuture <Self :: Iter >
157+ ) {
158+ let ( ip, port) = * self ;
159+ SocketAddrV4 :: new ( ip, port) . to_socket_addrs ( )
106160 }
107161}
108162
109163impl ToSocketAddrs for ( Ipv6Addr , u16 ) {
110164 type Iter = std:: option:: IntoIter < SocketAddr > ;
111165
112- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
113- ToSocketAddrsFuture :: Ready ( Some ( std:: net:: ToSocketAddrs :: to_socket_addrs ( self ) ) )
166+ fn to_socket_addrs (
167+ & self ,
168+ ) -> ret ! (
169+ impl Future <Output = Self :: Iter >,
170+ ToSocketAddrsFuture <Self :: Iter >
171+ ) {
172+ let ( ip, port) = * self ;
173+ SocketAddrV6 :: new ( ip, port, 0 , 0 ) . to_socket_addrs ( )
114174 }
115175}
116176
117177impl ToSocketAddrs for ( & str , u16 ) {
118178 type Iter = std:: vec:: IntoIter < SocketAddr > ;
119179
120- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
121- let host = self . 0 . to_string ( ) ;
122- let port = self . 1 ;
123- let join = blocking:: spawn ( async move {
180+ fn to_socket_addrs (
181+ & self ,
182+ ) -> ret ! (
183+ impl Future <Output = Self :: Iter >,
184+ ToSocketAddrsFuture <Self :: Iter >
185+ ) {
186+ let ( host, port) = * self ;
187+
188+ if let Ok ( addr) = host. parse :: < Ipv4Addr > ( ) {
189+ let addr = SocketAddrV4 :: new ( addr, port) ;
190+ return ToSocketAddrsFuture :: Ready ( Ok ( vec ! [ SocketAddr :: V4 ( addr) ] . into_iter ( ) ) ) ;
191+ }
192+
193+ if let Ok ( addr) = host. parse :: < Ipv6Addr > ( ) {
194+ let addr = SocketAddrV6 :: new ( addr, port, 0 , 0 ) ;
195+ return ToSocketAddrsFuture :: Ready ( Ok ( vec ! [ SocketAddr :: V6 ( addr) ] . into_iter ( ) ) ) ;
196+ }
197+
198+ let host = host. to_string ( ) ;
199+ let task = blocking:: spawn ( async move {
124200 std:: net:: ToSocketAddrs :: to_socket_addrs ( & ( host. as_str ( ) , port) )
125201 } ) ;
126- ToSocketAddrsFuture :: Join ( join )
202+ ToSocketAddrsFuture :: Resolving ( task )
127203 }
128204}
129205
130206impl ToSocketAddrs for str {
131207 type Iter = std:: vec:: IntoIter < SocketAddr > ;
132208
133- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
134- let socket_addrs = self . to_string ( ) ;
135- let join =
136- blocking:: spawn ( async move { std:: net:: ToSocketAddrs :: to_socket_addrs ( & socket_addrs) } ) ;
137- ToSocketAddrsFuture :: Join ( join)
209+ fn to_socket_addrs (
210+ & self ,
211+ ) -> ret ! (
212+ impl Future <Output = Self :: Iter >,
213+ ToSocketAddrsFuture <Self :: Iter >
214+ ) {
215+ if let Some ( addr) = self . parse ( ) . ok ( ) {
216+ return ToSocketAddrsFuture :: Ready ( Ok ( vec ! [ addr] . into_iter ( ) ) ) ;
217+ }
218+
219+ let addr = self . to_string ( ) ;
220+ let task =
221+ blocking:: spawn ( async move { std:: net:: ToSocketAddrs :: to_socket_addrs ( addr. as_str ( ) ) } ) ;
222+ ToSocketAddrsFuture :: Resolving ( task)
138223 }
139224}
140225
141226impl < ' a > ToSocketAddrs for & ' a [ SocketAddr ] {
142227 type Iter = std:: iter:: Cloned < std:: slice:: Iter < ' a , SocketAddr > > ;
143228
144- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
145- ToSocketAddrsFuture :: Ready ( Some ( std:: net:: ToSocketAddrs :: to_socket_addrs ( self ) ) )
229+ fn to_socket_addrs (
230+ & self ,
231+ ) -> ret ! (
232+ impl Future <Output = Self :: Iter >,
233+ ToSocketAddrsFuture <Self :: Iter >
234+ ) {
235+ ToSocketAddrsFuture :: Ready ( Ok ( self . iter ( ) . cloned ( ) ) )
146236 }
147237}
148238
149239impl < T : ToSocketAddrs + ?Sized > ToSocketAddrs for & T {
150240 type Iter = T :: Iter ;
151241
152- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
242+ fn to_socket_addrs (
243+ & self ,
244+ ) -> ret ! (
245+ impl Future <Output = Self :: Iter >,
246+ ToSocketAddrsFuture <Self :: Iter >
247+ ) {
153248 ( * * self ) . to_socket_addrs ( )
154249 }
155250}
156251
157252impl ToSocketAddrs for String {
158253 type Iter = std:: vec:: IntoIter < SocketAddr > ;
159254
160- fn to_socket_addrs ( & self ) -> ret ! ( ' _, ToSocketAddrsFuture , Self :: Iter ) {
161- ToSocketAddrs :: to_socket_addrs ( self . as_str ( ) )
255+ fn to_socket_addrs (
256+ & self ,
257+ ) -> ret ! (
258+ impl Future <Output = Self :: Iter >,
259+ ToSocketAddrsFuture <Self :: Iter >
260+ ) {
261+ ( & * * self ) . to_socket_addrs ( )
162262 }
163263}
0 commit comments