So - trying to get something that changes at runtime but satisfies a particular Trait... seems it's either:
- Wrap everything in enums
- Use Trait Objects
Fine. But now I want to get that as a Future... going the Trait Objects route, seems that I then need to also have the Future be a Trait Object, which means it needs to be boxed as well? (not totally clear on why... just where I ended up with fighting the compiler)
Here's the best I could do. Any tips?
Playground: Rust Playground
use std::fmt::{Display, Formatter, Result};
use futures::*;
struct Foo {}
struct Bar {}
impl Display for Foo {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "foo")
}
}
impl Display for Bar {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "bar")
}
}
impl Foo {
fn new() -> impl Future<Item = Box<Foo>, Error = ()> {
future::ok(Box::new(Foo{}))
}
}
impl Bar {
fn new() -> impl Future<Item = Box<Bar>, Error = ()> {
future::ok(Box::new(Bar{}))
}
}
//Can't do this
/*
fn get_dynamic_future (name:&str) -> impl Future<Item = Box<dyn Display + Send>, Error = ()> {
match name {
"foo" => Foo::new().map(|v| v as Box<Display + Send>),
"bar" => Foo::new().map(|v| v as Box<Display + Send>),
_ => future::err(())
}
}
*/
//Gotta do this??
fn get_dynamic_future (name:&str) -> Box<dyn Future<Item = Box<dyn Display + Send>, Error = ()> + Send> {
match name {
"foo" => Box::new(Foo::new().map(|v| v as Box<Display + Send>)),
"bar" => Box::new(Bar::new().map(|v| v as Box<Display + Send>)),
_ => Box::new(future::err(()))
}
}
fn main() {
tokio::run(get_dynamic_future("foo").map(|value| {
println!("{}", value);
()
}));
tokio::run(get_dynamic_future("bar").map(|value| {
println!("{}", value);
()
}));
}