mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-08 00:00:13 +02:00
fs: add CloneFuture for File::try_clone (#850)
This commit is contained in:
committed by
Carl Lerche
parent
3d787b16c7
commit
ab206b976c
@@ -0,0 +1,37 @@
|
|||||||
|
use super::File;
|
||||||
|
|
||||||
|
use futures::{Future, Poll};
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
/// Future returned by `File::try_clone`.
|
||||||
|
///
|
||||||
|
/// Clones a file handle into two file handles.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Will panic if polled after returning an item or error.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CloneFuture {
|
||||||
|
file: Option<File>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CloneFuture {
|
||||||
|
pub(crate) fn new(file: File) -> Self {
|
||||||
|
Self { file: Some(file) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Future for CloneFuture {
|
||||||
|
type Item = (File, File);
|
||||||
|
type Error = (File, io::Error);
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
self.file
|
||||||
|
.as_mut()
|
||||||
|
.expect("Cannot poll `CloneFuture` after it resolves")
|
||||||
|
.poll_try_clone()
|
||||||
|
.map(|inner| inner.map(|cloned| (self.file.take().unwrap(), cloned)))
|
||||||
|
.map_err(|err| (self.file.take().unwrap(), err))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,12 +2,14 @@
|
|||||||
//!
|
//!
|
||||||
//! [`File`]: file/struct.File.html
|
//! [`File`]: file/struct.File.html
|
||||||
|
|
||||||
|
mod clone;
|
||||||
mod create;
|
mod create;
|
||||||
mod metadata;
|
mod metadata;
|
||||||
mod open;
|
mod open;
|
||||||
mod open_options;
|
mod open_options;
|
||||||
mod seek;
|
mod seek;
|
||||||
|
|
||||||
|
pub use self::clone::CloneFuture;
|
||||||
pub use self::create::CreateFuture;
|
pub use self::create::CreateFuture;
|
||||||
pub use self::metadata::MetadataFuture;
|
pub use self::metadata::MetadataFuture;
|
||||||
pub use self::open::OpenFuture;
|
pub use self::open::OpenFuture;
|
||||||
@@ -407,6 +409,38 @@ impl File {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new `File` instance that shares the same underlying file handle
|
||||||
|
/// as the existing `File` instance. Reads, writes, and seeks will affect both
|
||||||
|
/// File instances simultaneously.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```no_run
|
||||||
|
/// # extern crate tokio;
|
||||||
|
/// use tokio::prelude::Future;
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let task = tokio::fs::File::create("foo.txt")
|
||||||
|
/// .and_then(|file| {
|
||||||
|
/// file.try_clone()
|
||||||
|
/// .map(|(file, clone)| {
|
||||||
|
/// // do something with the file and the clone
|
||||||
|
/// # println!("{:?} {:?}", file, clone);
|
||||||
|
/// })
|
||||||
|
/// .map_err(|(file, err)| {
|
||||||
|
/// // you get the original file back if there's an error
|
||||||
|
/// # println!("{:?}", file);
|
||||||
|
/// err
|
||||||
|
/// })
|
||||||
|
/// })
|
||||||
|
/// .map_err(|err| eprintln!("IO error: {:?}", err));
|
||||||
|
///
|
||||||
|
/// tokio::run(task);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn try_clone(self) -> CloneFuture {
|
||||||
|
CloneFuture::new(self)
|
||||||
|
}
|
||||||
|
|
||||||
/// Changes the permissions on the underlying file.
|
/// Changes the permissions on the underlying file.
|
||||||
///
|
///
|
||||||
/// # Platform-specific behavior
|
/// # Platform-specific behavior
|
||||||
|
|||||||
@@ -125,3 +125,35 @@ fn seek() {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn clone() {
|
||||||
|
let dir = TmpBuilder::new()
|
||||||
|
.prefix("tokio-fs-tests")
|
||||||
|
.tempdir()
|
||||||
|
.unwrap();
|
||||||
|
let file_path = dir.path().join("clone.txt");
|
||||||
|
|
||||||
|
pool::run(
|
||||||
|
File::create(file_path.clone())
|
||||||
|
.and_then(|file| {
|
||||||
|
file.try_clone()
|
||||||
|
.map_err(|(_file, err)| err)
|
||||||
|
.and_then(|(file, clone)| {
|
||||||
|
io::write_all(file, "clone ")
|
||||||
|
.and_then(|_| io::write_all(clone, "successful"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(|res| {
|
||||||
|
let _ = res.unwrap();
|
||||||
|
Ok(())
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut file = StdFile::open(&file_path).unwrap();
|
||||||
|
|
||||||
|
let mut dst = vec![];
|
||||||
|
file.read_to_end(&mut dst).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(dst, b"clone successful")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user