@@ -352,7 +352,80 @@ impl FromStr for SocketAddr {
352
352
}
353
353
}
354
354
355
+ /// A trait for objects which can be converted or resolved to one or more `SocketAddr` values.
356
+ ///
357
+ /// Implementing types minimally have to implement either `to_socket_addr` or `to_socket_addr_all`
358
+ /// method, and its trivial counterpart will be available automatically.
359
+ ///
360
+ /// This trait is used for generic address resolution when constructing network objects.
361
+ /// By default it is implemented for the following types:
362
+ ///
363
+ /// * `SocketAddr` - `to_socket_addr` is identity function.
364
+ ///
365
+ /// * `(IpAddr, u16)` - `to_socket_addr` constructs `SocketAddr` trivially.
366
+ ///
367
+ /// * `(&str, u16)` - the string should be either a string representation of an IP address
368
+ /// expected by `FromStr` implementation for `IpAddr` or a host name.
369
+ ///
370
+ /// For the former, `to_socket_addr_all` returns a vector with a single element corresponding
371
+ /// to that IP address joined with the given port.
372
+ ///
373
+ /// For the latter, it tries to resolve the host name and returns a vector of all IP addresses
374
+ /// for the host name, each joined with the given port.
375
+ ///
376
+ /// * `&str` - the string should be either a string representation of a `SocketAddr` as
377
+ /// expected by its `FromStr` implementation or a string like `<host_name>:<port>` pair
378
+ /// where `<port>` is a `u16` value.
379
+ ///
380
+ /// For the former, `to_socker_addr_all` returns a vector with a single element corresponding
381
+ /// to that socker address.
382
+ ///
383
+ /// For the latter, it tries to resolve the host name and returns a vector of all IP addresses
384
+ /// for the host name, each joined with the port.
385
+ ///
386
+ ///
387
+ /// This trait allows constructing network objects like `TcpStream` or `UdpSocket` easily with
388
+ /// values of various types for the bind/connection address. It is needed because sometimes
389
+ /// one type is more appropriate than the other: for simple uses a string like `"localhost:12345"`
390
+ /// is much nicer than manual construction of the corresponding `SocketAddr`, but sometimes
391
+ /// `SocketAddr` value is *the* main source of the address, and converting it to some other type
392
+ /// (e.g. a string) just for it to be converted back to `SocketAddr` in constructor methods
393
+ /// is pointless.
394
+ ///
395
+ /// Some examples:
396
+ ///
397
+ /// ```rust,no_run
398
+ /// # #![allow(unused_must_use)]
399
+ ///
400
+ /// use std::io::{TcpStream, TcpListener};
401
+ /// use std::io::net::udp::UdpSocket;
402
+ /// use std::io::net::ip::{ToSocketAddr, Ipv4Addr, SocketAddr};
403
+ ///
404
+ /// fn main() {
405
+ /// // The following lines are equivalent modulo possible "localhost" name resolution
406
+ /// // differences
407
+ /// let tcp_s = TcpStream::connect(SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 12345 });
408
+ /// let tcp_s = TcpStream::connect((Ipv4Addr(127, 0, 0, 1), 12345u16));
409
+ /// let tcp_s = TcpStream::connect(("127.0.0.1", 12345u16));
410
+ /// let tcp_s = TcpStream::connect(("localhost", 12345u16));
411
+ /// let tcp_s = TcpStream::connect("127.0.0.1:12345");
412
+ /// let tcp_s = TcpStream::connect("localhost:12345");
413
+ ///
414
+ /// // TcpListener::bind(), UdpSocket::bind() and UdpSocket::send_to() behave similarly
415
+ /// let tcp_l = TcpListener::bind("localhost:12345");
416
+ ///
417
+ /// let udp_s = UdpSocket::bind(("127.0.0.1", 23451u16));
418
+ /// udp_s.send_to([7u8, 7u8, 7u8].as_slice(), (Ipv4Addr(127, 0, 0, 1), 23451u16));
419
+ /// }
420
+ /// ```
355
421
pub trait ToSocketAddr {
422
+ /// Converts this object to single socket address value.
423
+ ///
424
+ /// If more than one value is available, this method returns the first one. If no
425
+ /// values are available, this method returns an `IoError`.
426
+ ///
427
+ /// By default this method delegates to `to_socket_addr_all` method, taking the first
428
+ /// item from its result.
356
429
fn to_socket_addr ( & self ) -> IoResult < SocketAddr > {
357
430
self . to_socket_addr_all ( )
358
431
. and_then ( |v| v. into_iter ( ) . next ( ) . ok_or_else ( || IoError {
@@ -362,6 +435,13 @@ pub trait ToSocketAddr {
362
435
} ) )
363
436
}
364
437
438
+ /// Converts this object to all available socket address values.
439
+ ///
440
+ /// Some values like host name string naturally corrrespond to multiple IP addresses.
441
+ /// This method tries to return all available addresses corresponding to this object.
442
+ ///
443
+ /// By default this method delegates to `to_socket_addr` method, creating a singleton
444
+ /// vector from its result.
365
445
#[ inline]
366
446
fn to_socket_addr_all ( & self ) -> IoResult < Vec < SocketAddr > > {
367
447
self . to_socket_addr ( ) . map ( |a| vec ! [ a] )
0 commit comments