Hello!
#[derive(Clone, Copy, Debug)]
pub struct PortRange {
first: u16,
last: u16,
}
pub trait ToPortRange {
fn to_port_range(&self) -> PortRange;
}
pub struct AllPorts {}
impl ToPortRange for AllPorts {
fn to_port_range(&self) -> PortRange {
PortRange {
first: 1,
last: 65353,
}
}
}
struct BrightLightUdpClientBuilder<R> {
port_ranges: R,
}
impl<'a, R> BrightLightUdpClientBuilder<R>
where
R: IntoIterator<Item = &'a dyn ToPortRange>,
{
fn new(port_ranges: R) -> Self {
Self {
port_ranges,
}
}
fn build(self) {
for pr in self.port_ranges.into_iter() {
println!("{:?}", pr.to_port_range());
}
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!();
let port_ranges: Option<&dyn ToPortRange> = Some(&AllPorts{});
let builder = BrightLightUdpClientBuilder::new(port_ranges);
builder.build();
// --- Why does this not work when the one above does?
let builder = BrightLightUdpClientBuilder::new(Some(&AllPorts{}));
//builder.build();
/*
error[E0271]: type mismatch resolving `<Option<&AllPorts> as IntoIterator>::Item == &dyn ToPortRange`
--> src\main.rs:113:19
|
113 | let builder = BrightLightUdpClientBuilder::new(Some(&AllPorts{}));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn ToPortRange`, found struct `AllPorts`
|
= note: expected reference `&dyn ToPortRange`
found reference `&AllPorts`
note: required by a bound in `BrightLightUdpClientBuilder::<R>::new`
--> src\main.rs:88:21
|
88 | R: IntoIterator<Item = &'a dyn ToPortRange>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `BrightLightUdpClientBuilder::<R>::new`
89 | {
90 | fn new(port_ranges: R) -> Self {
| --- required by a bound in this
*/
println!();
Ok(())
}
I'd really like let builder = BrightLightUdpClientBuilder::new(Some(&AllPorts{}));
to work (in addition to being able to pass a Vec
). I just cannot find an incantation that appeases the compiler.
Is it possible to coerce the &AllPorts
to be a &dyn ToPortRange
?