Add a dedicated Future for retrieving the metadata of a file (#385)

This commit is contained in:
Jake Goulding
2018-06-18 16:00:43 -07:00
committed by Carl Lerche
parent 85cf47de86
commit b2f77dcebe
3 changed files with 49 additions and 1 deletions
+39
View File
@@ -0,0 +1,39 @@
use super::File;
use futures::{Future, Poll};
use std::fs::File as StdFile;
use std::fs::Metadata;
use std::io;
const POLL_AFTER_RESOLVE: &str = "Cannot poll MetadataFuture after it resolves";
/// Future returned by `File::metadata` and resolves to a `(Metadata, File)` instance.
#[derive(Debug)]
pub struct MetadataFuture {
file: Option<File>,
}
impl MetadataFuture {
pub(crate) fn new(file: File) -> Self {
MetadataFuture { file: Some(file) }
}
fn std(&mut self) -> &mut StdFile {
self.file.as_mut().expect(POLL_AFTER_RESOLVE).std()
}
}
impl Future for MetadataFuture {
type Item = (File, Metadata);
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let metadata = try_ready!(::blocking_io(|| {
StdFile::metadata(self.std())
}));
let file = self.file.take().expect(POLL_AFTER_RESOLVE);
Ok((file, metadata).into())
}
}
+7
View File
@@ -3,10 +3,12 @@
//! [`File`]: file/struct.File.html
mod create;
mod metadata;
mod open;
mod open_options;
pub use self::create::CreateFuture;
pub use self::metadata::MetadataFuture;
pub use self::open::OpenFuture;
pub use self::open_options::OpenOptions;
@@ -133,6 +135,11 @@ impl File {
::blocking_io(|| self.std().set_len(size))
}
/// Queries metadata about the underlying file.
pub fn metadata(self) -> MetadataFuture {
MetadataFuture::new(self)
}
/// Queries metadata about the underlying file.
pub fn poll_metadata(&mut self) -> Poll<Metadata, io::Error> {
::blocking_io(|| self.std().metadata())
+3 -1
View File
@@ -41,7 +41,9 @@ fn read_write() {
let contents = contents.clone();
File::create(file_path)
.and_then(move |file| io::write_all(file, contents))
.and_then(|file| file.metadata())
.inspect(|&(_, ref metadata)| assert!(metadata.is_file()))
.and_then(move |(file, _)| io::write_all(file, contents))
.and_then(|(mut file, _)| {
poll_fn(move || file.poll_sync_all())
})