diff --git a/src/macros.rs b/src/macros.rs index 336e64c..d6ea8d9 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -531,15 +531,7 @@ macro_rules! service { -> ::std::io::Result<$crate::tokio_proto::server::ServerHandle> where L: ::std::net::ToSocketAddrs { - let addr = if let ::std::option::Option::Some(a) = - ::std::iter::Iterator::next( - &mut ::std::net::ToSocketAddrs::to_socket_addrs(&addr)?) { - a - } else { - return Err(::std::io::Error::new(::std::io::ErrorKind::AddrNotAvailable, - "`ToSocketAddrs::to_socket_addrs` returned an empty iterator.")); - }; - + let addr = $crate::util::FirstSocketAddr::try_first_socket_addr(&addr)?; let __tarpc_service_service = __SyncServer { service: self, }; @@ -603,17 +595,7 @@ macro_rules! service { fn connect(addr: A) -> ::std::result::Result where A: ::std::net::ToSocketAddrs, { - let addr = if let ::std::option::Option::Some(a) = - ::std::iter::Iterator::next( - &mut ::std::net::ToSocketAddrs::to_socket_addrs(&addr)?) - { - a - } else { - return ::std::result::Result::Err( - ::std::io::Error::new( - ::std::io::ErrorKind::AddrNotAvailable, - "`ToSocketAddrs::to_socket_addrs` returned an empty iterator.")); - }; + let addr = $crate::util::FirstSocketAddr::try_first_socket_addr(&addr)?; let client = ::connect(&addr); let client = SyncClient($crate::futures::Future::wait(client)?); ::std::result::Result::Ok(client) diff --git a/src/util.rs b/src/util.rs index c1e842a..4166d65 100644 --- a/src/util.rs +++ b/src/util.rs @@ -7,10 +7,9 @@ use futures::{self, Future, Poll}; use futures::stream::Stream; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::error::Error; -use std::fmt; +use std::{fmt, io, thread}; use std::net::{SocketAddr, ToSocketAddrs}; use std::sync::mpsc; -use std::thread; use tokio_core::reactor; /// A bottom type that impls `Error`, `Serialize`, and `Deserialize`. It is impossible to @@ -103,12 +102,22 @@ impl> From for Message { } -/// Provides a utility method for more ergonomically parsing a `SocketAddr` when panicking is -/// acceptable. +/// Provides a utility method for more ergonomically parsing a `SocketAddr` when only one is +/// needed. pub trait FirstSocketAddr: ToSocketAddrs { + /// Returns the first resolved `SocketAddr`, if one exists. + fn try_first_socket_addr(&self) -> io::Result { + if let Some(a) = self.to_socket_addrs()?.next() { + Ok(a) + } else { + Err(io::Error::new(io::ErrorKind::AddrNotAvailable, + "`ToSocketAddrs::to_socket_addrs` returned an empty iterator.")) + } + } + /// Returns the first resolved `SocketAddr` or panics otherwise. fn first_socket_addr(&self) -> SocketAddr { - self.to_socket_addrs().unwrap().next().unwrap() + self.try_first_socket_addr().unwrap() } }