It seems like it ought to be possible to use Iterator::map (and other iterator combinators) to avoid a lot of extra typing when defining a ToSocketAddrs impl, something like this:
use std::io;
use std::iter;
use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
use std::range::{Range, RangeIter};
pub struct PortRange {
addr: IpAddr,
range: Range<u16>,
}
impl PortRange {
pub fn new(addr: IpAddr, range: Range<u16>) -> PortRange {
PortRange { addr, range }
}
}
impl ToSocketAddrs for PortRange {
type Iter = iter::Map<RangeIter<u16>, _>; // <-- problem here
fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
Ok(self
.range
.iter()
.map(|port| SocketAddr::new(self.addr, port)))
}
}
The problem is that the second type argument to iter::Map needs to be the type of the closure, or something close to it, and I haven't been able to find a way to name that type. If you compile the above as is you get
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
I tried changing the placeholder to FnMut(u16)->SocketAddr and impl FnMut(u16)->SocketAddr but those just gave me different errors.