Я работаю с Токио, выполняя некоторые операции с UDP.
Я хочу записать количество времени, которое понадобится моему будущему зонду UDP для разрешения.Я придумал следующую функцию, time_future()
, чтобы обернуть будущее и дать мне результат и продолжительность.Эта функция кажется очень наивной, и я думаю, что Rust обладает способностью выразить концепцию гораздо более четко.
Мой рабочий код ( Детская площадка ):
extern crate futures; // 0.1.25
extern crate tokio; // 0.1.11
use std::time::{Duration, Instant};
use futures::future::{lazy, ok};
use futures::Future;
use tokio::runtime::current_thread::Runtime;
use tokio::timer::Delay;
struct TimedFutureResult<T, E> {
elapsed: Duration,
result: Result<T, E>,
}
impl<T, E> TimedFutureResult<T, E> {
pub fn elapsed_ms(&self) -> i64 {
return (self.elapsed.as_secs() * 1000 + (self.elapsed.subsec_nanos() / 1000000) as u64)
as i64;
}
}
fn time_future<F: Future>(f: F) -> impl Future<Item = TimedFutureResult<F::Item, F::Error>> {
lazy(|| {
let start = Instant::now();
f.then(move |result| {
ok::<TimedFutureResult<F::Item, F::Error>, ()>(TimedFutureResult {
elapsed: start.elapsed(),
result: result,
})
})
})
}
fn main() {
let when = Instant::now() + Duration::from_millis(100);
let f = time_future(Delay::new(when)).then(|r| match r {
Ok(r) => {
println!("resolved in {}ms", r.elapsed_ms());
r.result
}
_ => unreachable!(),
});
let mut runtime = Runtime::new().unwrap();
runtime.block_on(f).unwrap();
}
Как можноЯ улучшу это и сделаю это более идиоматичным?Можно ли как-то заставить интерфейс работать так же, как inspect()
или then()
?
Delay::new(when)
.timed(|res, elapsed| println!("{}ms!", elapsed))
.and_then(...);
Я пытался создать черту Timed
и реализовать ее для Future
, но я совсем не чувствовалуверенный в том, как я собирался об этом.Типы просто бросили меня в тупик.
Я хотя бы лаю на правильное дерево?