Reputation: 10960
I'm trying to write a function which would return a Future
, so following a tutorial from Tokio, I came up with this:
extern crate tokio;
use std::time::{Duration, Instant};
use tokio::prelude::*;
use tokio::timer::Interval;
fn run<F>() -> impl Future<Item = (), Error = F::Error>
where
F: Future<Item = ()>,
{
Interval::new(Instant::now(), Duration::from_millis(1000))
.for_each(move |instant| {
println!("fire; instant={:?}", instant);
Ok(())
})
.map_err(|e| panic!("interval errored; err={:?}", e))
}
fn main() {
tokio::run(run());
}
I get this error:
error[E0282]: type annotations needed
--> src/main.rs:20:16
|
20 | tokio::run(run());
| ^^^ cannot infer type for `F`
I assume the error will go away once I specify the full return type, which I can't even figure out (my IDE gives me <futures::MapErr<futures::stream::ForEach<tokio::timer::Interval, [closure@src/ir.rs:24:23: 38:14 self:_], std::result::Result<(), tokio::timer::Error>>, [closure@src/ir.rs:39:22: 39:65]>
)
How can I figure out the type? Any IDE tips or tricks? (I'm using Atom with ide-rust)
Can I somehow get away with just defining impl Future<Item = (), Error = F::Error> where F: Future<Item = ()>
?
I'm fine with defining the full type somewhere inside of run
function, but to the outside of the function I'd like to expose <Future<Item = (), Error = F::Error>>
or <Future<Item = (), Error = io::Error>>
Upvotes: 0
Views: 498
Reputation: 18943
Look at tokio::run
's signature:
pub fn run<F>(future: F)
where
F: Future<Item = (), Error = ()> + Send + 'static,
The consumed future must have the associated Error
type equal to ()
. This implies that you cannot be generic over the error.
This works:
fn run() -> impl Future<Item = (), Error = ()> {
Interval::new(Instant::now(), Duration::from_millis(1000))
.for_each(move |instant| {
println!("fire; instant={:?}", instant);
Ok(())
})
.map_err(|e| panic!("interval errored; err={:?}", e))
}
fn main() {
tokio::run(run());
}
Upvotes: 2