1
- use std:: marker :: PhantomData ;
1
+ use std:: mem ;
2
2
use std:: net:: { IpAddr , Ipv4Addr , Ipv6Addr } ;
3
3
use std:: net:: { SocketAddr , SocketAddrV4 , SocketAddrV6 } ;
4
4
use std:: pin:: Pin ;
@@ -12,24 +12,37 @@ use crate::task::{blocking, Context, JoinHandle, Poll};
12
12
cfg_if ! {
13
13
if #[ cfg( feature = "docs" ) ] {
14
14
#[ doc( hidden) ]
15
- pub struct ImplFuture <' a , T >( std:: marker:: PhantomData <& ' a T >) ;
15
+ pub struct ImplFuture <T >( std:: marker:: PhantomData <T >) ;
16
16
17
17
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 >) ;
19
19
}
20
20
} else {
21
21
macro_rules! ret {
22
- ( $a : lifetime , $f : tt , $i : ty) => ( $f<$a , $i> ) ;
22
+ ( impl Future < Output = $out : ty> , $fut : ty) => ( $fut ) ;
23
23
}
24
24
}
25
25
}
26
26
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.
28
28
///
29
29
/// This trait is an async version of [`std::net::ToSocketAddrs`].
30
30
///
31
31
/// [`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
+ /// ```
33
46
pub trait ToSocketAddrs {
34
47
/// Returned iterator over socket addresses which this type may correspond to.
35
48
type Iter : Iterator < Item = SocketAddr > ;
@@ -40,124 +53,211 @@ pub trait ToSocketAddrs {
40
53
/// resolution performed.
41
54
///
42
55
/// 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
+ ) ;
44
62
}
45
63
46
64
#[ doc( hidden) ]
47
65
#[ 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 ,
52
70
}
53
71
54
- impl < I : Iterator < Item = SocketAddr > > Future for ToSocketAddrsFuture < ' _ , I > {
72
+ impl < I : Iterator < Item = SocketAddr > > Future for ToSocketAddrsFuture < I > {
55
73
type Output = io:: Result < I > ;
56
74
57
75
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
63
86
}
64
- _ => unreachable ! ( ) ,
87
+ ToSocketAddrsFuture :: Ready ( res) => Poll :: Ready ( res) ,
88
+ ToSocketAddrsFuture :: Done => panic ! ( "polled a completed future" ) ,
65
89
}
66
90
}
67
91
}
68
92
69
93
impl ToSocketAddrs for SocketAddr {
70
94
type Iter = std:: option:: IntoIter < SocketAddr > ;
71
95
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 ( ) ) )
74
103
}
75
104
}
76
105
77
106
impl ToSocketAddrs for SocketAddrV4 {
78
107
type Iter = std:: option:: IntoIter < SocketAddr > ;
79
108
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 ( )
82
116
}
83
117
}
84
118
85
119
impl ToSocketAddrs for SocketAddrV6 {
86
120
type Iter = std:: option:: IntoIter < SocketAddr > ;
87
121
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 ( )
90
129
}
91
130
}
92
131
93
132
impl ToSocketAddrs for ( IpAddr , u16 ) {
94
133
type Iter = std:: option:: IntoIter < SocketAddr > ;
95
134
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
+ }
98
146
}
99
147
}
100
148
101
149
impl ToSocketAddrs for ( Ipv4Addr , u16 ) {
102
150
type Iter = std:: option:: IntoIter < SocketAddr > ;
103
151
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 ( )
106
160
}
107
161
}
108
162
109
163
impl ToSocketAddrs for ( Ipv6Addr , u16 ) {
110
164
type Iter = std:: option:: IntoIter < SocketAddr > ;
111
165
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 ( )
114
174
}
115
175
}
116
176
117
177
impl ToSocketAddrs for ( & str , u16 ) {
118
178
type Iter = std:: vec:: IntoIter < SocketAddr > ;
119
179
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 {
124
200
std:: net:: ToSocketAddrs :: to_socket_addrs ( & ( host. as_str ( ) , port) )
125
201
} ) ;
126
- ToSocketAddrsFuture :: Join ( join )
202
+ ToSocketAddrsFuture :: Resolving ( task )
127
203
}
128
204
}
129
205
130
206
impl ToSocketAddrs for str {
131
207
type Iter = std:: vec:: IntoIter < SocketAddr > ;
132
208
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)
138
223
}
139
224
}
140
225
141
226
impl < ' a > ToSocketAddrs for & ' a [ SocketAddr ] {
142
227
type Iter = std:: iter:: Cloned < std:: slice:: Iter < ' a , SocketAddr > > ;
143
228
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 ( ) ) )
146
236
}
147
237
}
148
238
149
239
impl < T : ToSocketAddrs + ?Sized > ToSocketAddrs for & T {
150
240
type Iter = T :: Iter ;
151
241
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
+ ) {
153
248
( * * self ) . to_socket_addrs ( )
154
249
}
155
250
}
156
251
157
252
impl ToSocketAddrs for String {
158
253
type Iter = std:: vec:: IntoIter < SocketAddr > ;
159
254
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 ( )
162
262
}
163
263
}
0 commit comments