use futures::{Async::*, Future, Poll};
use std::fs::Metadata;
use std::io::Error;
use std::path::PathBuf;
use tokio::fs::{File, file::OpenFuture};
enum OpenWithMetadataState {
WaitOpen(OpenFuture<PathBuf>),
WaitMetadata,
Done,
}
pub struct OpenWithMetadataFuture {
state: OpenWithMetadataState,
file: Option<File>,
metadata: Option<Metadata>,
}
impl Future for OpenWithMetadataFuture {
type Item = (File, Metadata);
type Error = Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
loop {
self.state = match self.state {
OpenWithMetadataState::WaitOpen(ref mut future) => {
self.file = Some(try_ready!(future.poll()));
OpenWithMetadataState::WaitMetadata
},
OpenWithMetadataState::WaitMetadata => {
let file = self.file.as_mut().expect("invalid state");
self.metadata = Some(try_ready!(file.poll_metadata()));
OpenWithMetadataState::Done
},
OpenWithMetadataState::Done => {
let file = self.file.take().expect("invalid state");
let metadata = self.metadata.take().expect("invalid state");
return Ok(Ready((file, metadata)));
},
}
}
}
}
pub fn open_with_metadata(path: PathBuf) -> OpenWithMetadataFuture {
let state = OpenWithMetadataState::WaitOpen(File::open(path));
OpenWithMetadataFuture { state, file: None, metadata: None }
}