diff --git a/src/fs.rs b/src/fs.rs index f0ed9a530..689a60136 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -7,4 +7,6 @@ //! the context of the Tokio runtime as they require Tokio specific features to //! function. -pub use tokio_fs::{file, metadata, File, OpenOptions}; +pub use tokio_fs::{create_dir, create_dir_all, file, hard_link, metadata, os, read_dir, read_link}; +pub use tokio_fs::{remove_dir, remove_file, rename, set_permissions, symlink_metadata, File}; +pub use tokio_fs::OpenOptions; diff --git a/tokio-fs/Cargo.toml b/tokio-fs/Cargo.toml index c16c69488..8cde466be 100644 --- a/tokio-fs/Cargo.toml +++ b/tokio-fs/Cargo.toml @@ -28,3 +28,4 @@ rand = "0.4.2" tempdir = "0.3.7" tokio-io = { version = "0.1.6", path = "../tokio-io" } tokio-codec = { version = "0.1.0", path = "../tokio-codec" } +tokio = { version = "0.1.7", path = ".." } diff --git a/tokio-fs/src/create_dir.rs b/tokio-fs/src/create_dir.rs new file mode 100644 index 000000000..a174a5d97 --- /dev/null +++ b/tokio-fs/src/create_dir.rs @@ -0,0 +1,46 @@ +use std::fs; +use std::io; +use std::path::Path; + +use futures::{Future, Poll}; + +/// Creates a new, empty directory at the provided path +/// +/// This is an async version of [`std::fs::create_dir`][std] +/// +/// [std]: https://doc.rust-lang.org/std/fs/fn.create_dir.html +pub fn create_dir>(path: P) -> CreateDirFuture

{ + CreateDirFuture::new(path) +} + +/// Future returned by `create_dir`. +#[derive(Debug)] +pub struct CreateDirFuture

+where + P: AsRef +{ + path: P, +} + +impl

CreateDirFuture

+where + P: AsRef +{ + fn new(path: P) -> CreateDirFuture

{ + CreateDirFuture { + path: path, + } + } +} + +impl

Future for CreateDirFuture

+where + P: AsRef +{ + type Item = (); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::create_dir(&self.path) ) + } +} diff --git a/tokio-fs/src/create_dir_all.rs b/tokio-fs/src/create_dir_all.rs new file mode 100644 index 000000000..3e3248067 --- /dev/null +++ b/tokio-fs/src/create_dir_all.rs @@ -0,0 +1,47 @@ +use std::fs; +use std::io; +use std::path::Path; + +use futures::{Future, Poll}; + +/// Recursively create a directory and all of its parent components if they +/// are missing. +/// +/// This is an async version of [`std::fs::create_dir_all`][std] +/// +/// [std]: https://doc.rust-lang.org/std/fs/fn.create_dir_all.html +pub fn create_dir_all>(path: P) -> CreateDirAllFuture

{ + CreateDirAllFuture::new(path) +} + +/// Future returned by `create_dir_all`. +#[derive(Debug)] +pub struct CreateDirAllFuture

+where + P: AsRef +{ + path: P, +} + +impl

CreateDirAllFuture

+where + P: AsRef +{ + fn new(path: P) -> CreateDirAllFuture

{ + CreateDirAllFuture { + path: path, + } + } +} + +impl

Future for CreateDirAllFuture

+where + P: AsRef +{ + type Item = (); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::create_dir_all(&self.path) ) + } +} diff --git a/tokio-fs/src/hard_link.rs b/tokio-fs/src/hard_link.rs new file mode 100644 index 000000000..e8ea51152 --- /dev/null +++ b/tokio-fs/src/hard_link.rs @@ -0,0 +1,54 @@ +use std::fs; +use std::io; +use std::path::Path; + +use futures::{Future, Poll}; + +/// Creates a new hard link on the filesystem. +/// +/// The `dst` path will be a link pointing to the `src` path. Note that systems +/// often require these two paths to both be located on the same filesystem. +/// +/// This is an async version of [`std::fs::hard_link`][std] +/// +/// [std]: https://doc.rust-lang.org/std/fs/fn.hard_link.html +pub fn hard_link, Q: AsRef>(src: P, dst: Q) -> HardLinkFuture { + HardLinkFuture::new(src, dst) +} + +/// Future returned by `hard_link`. +#[derive(Debug)] +pub struct HardLinkFuture +where + P: AsRef, + Q: AsRef +{ + src: P, + dst: Q, +} + +impl HardLinkFuture +where + P: AsRef, + Q: AsRef +{ + fn new(src: P, dst: Q) -> HardLinkFuture { + HardLinkFuture { + src: src, + dst: dst, + } + } +} + +impl Future for HardLinkFuture +where + P: AsRef, + Q: AsRef +{ + type Item = (); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::hard_link(&self.src, &self.dst) ) + } +} diff --git a/tokio-fs/src/lib.rs b/tokio-fs/src/lib.rs index 3ce63f817..1b266de87 100644 --- a/tokio-fs/src/lib.rs +++ b/tokio-fs/src/lib.rs @@ -33,18 +33,39 @@ extern crate futures; extern crate tokio_io; extern crate tokio_threadpool; +mod create_dir; +mod create_dir_all; pub mod file; +mod hard_link; mod metadata; +pub mod os; +mod read_dir; +mod read_link; +mod remove_dir; +mod remove_file; +mod rename; +mod set_permissions; mod stdin; mod stdout; mod stderr; +mod symlink_metadata; +pub use create_dir::{create_dir, CreateDirFuture}; +pub use create_dir_all::{create_dir_all, CreateDirAllFuture}; pub use file::File; pub use file::OpenOptions; +pub use hard_link::{hard_link, HardLinkFuture}; pub use metadata::{metadata, MetadataFuture}; +pub use read_dir::{read_dir, ReadDirFuture, ReadDir, DirEntry}; +pub use read_link::{read_link, ReadLinkFuture}; +pub use remove_dir::{remove_dir, RemoveDirFuture}; +pub use remove_file::{remove_file, RemoveFileFuture}; +pub use rename::{rename, RenameFuture}; +pub use set_permissions::{set_permissions, SetPermissionsFuture}; pub use stdin::{stdin, Stdin}; pub use stdout::{stdout, Stdout}; pub use stderr::{stderr, Stderr}; +pub use symlink_metadata::{symlink_metadata, SymlinkMetadataFuture}; use futures::Poll; use futures::Async::*; diff --git a/tokio-fs/src/os/mod.rs b/tokio-fs/src/os/mod.rs new file mode 100644 index 000000000..ae57c4847 --- /dev/null +++ b/tokio-fs/src/os/mod.rs @@ -0,0 +1,6 @@ +//! OS-specific functionality. + +#[cfg(unix)] +pub mod unix; +#[cfg(windows)] +pub mod windows; diff --git a/tokio-fs/src/os/unix.rs b/tokio-fs/src/os/unix.rs new file mode 100644 index 000000000..5f8eedeba --- /dev/null +++ b/tokio-fs/src/os/unix.rs @@ -0,0 +1,55 @@ +//! Unix-specific extensions to primitives in the `tokio_fs` module. + +use std::io; +use std::path::Path; +use std::os::unix::fs; + +use futures::{Future, Poll}; + +/// Creates a new symbolic link on the filesystem. +/// +/// The `dst` path will be a symbolic link pointing to the `src` path. +/// +/// This is an async version of [`std::os::unix::fs::symlink`][std] +/// +/// [std]: https://doc.rust-lang.org/std/os/unix/fs/fn.symlink.html +pub fn symlink, Q: AsRef>(src: P, dst: Q) -> SymlinkFuture { + SymlinkFuture::new(src, dst) +} + +/// Future returned by `symlink`. +#[derive(Debug)] +pub struct SymlinkFuture +where + P: AsRef, + Q: AsRef +{ + src: P, + dst: Q, +} + +impl SymlinkFuture +where + P: AsRef, + Q: AsRef +{ + fn new(src: P, dst: Q) -> SymlinkFuture { + SymlinkFuture { + src: src, + dst: dst, + } + } +} + +impl Future for SymlinkFuture +where + P: AsRef, + Q: AsRef +{ + type Item = (); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::symlink(&self.src, &self.dst) ) + } +} diff --git a/tokio-fs/src/os/windows/mod.rs b/tokio-fs/src/os/windows/mod.rs new file mode 100644 index 000000000..eaeed043e --- /dev/null +++ b/tokio-fs/src/os/windows/mod.rs @@ -0,0 +1,7 @@ +//! Windows-specific extensions for the primitives in the `tokio_fs` module. + +mod symlink_dir; +mod symlink_file; + +pub use self::symlink_dir::{symlink_dir, SymlinkDirFuture}; +pub use self::symlink_file::{symlink_file, SymlinkFileFuture}; diff --git a/tokio-fs/src/os/windows/symlink_dir.rs b/tokio-fs/src/os/windows/symlink_dir.rs new file mode 100644 index 000000000..9806ff3a3 --- /dev/null +++ b/tokio-fs/src/os/windows/symlink_dir.rs @@ -0,0 +1,54 @@ +use std::io; +use std::path::Path; +use std::os::windows::fs; + +use futures::{Future, Poll}; + +/// Creates a new directory symlink on the filesystem. +/// +/// The `dst` path will be a directory symbolic link pointing to the `src` +/// path. +/// +/// This is an async version of [`std::os::windows::fs::symlink_dir`][std] +/// +/// [std]: https://doc.rust-lang.org/std/os/windows/fs/fn.symlink_dir.html +pub fn symlink_dir, Q: AsRef>(src: P, dst: Q) -> SymlinkDirFuture { + SymlinkDirFuture::new(src, dst) +} + +/// Future returned by `symlink_dir`. +#[derive(Debug)] +pub struct SymlinkDirFuture +where + P: AsRef, + Q: AsRef +{ + src: P, + dst: Q, +} + +impl SymlinkDirFuture +where + P: AsRef, + Q: AsRef +{ + fn new(src: P, dst: Q) -> SymlinkDirFuture { + SymlinkDirFuture { + src: src, + dst: dst, + } + } +} + +impl Future for SymlinkDirFuture +where + P: AsRef, + Q: AsRef +{ + type Item = (); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::symlink_dir(&self.src, &self.dst) ) + } +} diff --git a/tokio-fs/src/os/windows/symlink_file.rs b/tokio-fs/src/os/windows/symlink_file.rs new file mode 100644 index 000000000..583b61587 --- /dev/null +++ b/tokio-fs/src/os/windows/symlink_file.rs @@ -0,0 +1,54 @@ +use std::io; +use std::path::Path; +use std::os::windows::fs; + +use futures::{Future, Poll}; + +/// Creates a new file symbolic link on the filesystem. +/// +/// The `dst` path will be a file symbolic link pointing to the `src` +/// path. +/// +/// This is an async version of [`std::os::windows::fs::symlink_file`][std] +/// +/// [std]: https://doc.rust-lang.org/std/os/windows/fs/fn.symlink_file.html +pub fn symlink_file, Q: AsRef>(src: P, dst: Q) -> SymlinkFileFuture { + SymlinkFileFuture::new(src, dst) +} + +/// Future returned by `symlink_file`. +#[derive(Debug)] +pub struct SymlinkFileFuture +where + P: AsRef, + Q: AsRef +{ + src: P, + dst: Q, +} + +impl SymlinkFileFuture +where + P: AsRef, + Q: AsRef +{ + fn new(src: P, dst: Q) -> SymlinkFileFuture { + SymlinkFileFuture { + src: src, + dst: dst, + } + } +} + +impl Future for SymlinkFileFuture +where + P: AsRef, + Q: AsRef +{ + type Item = (); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::symlink_file(&self.src, &self.dst) ) + } +} diff --git a/tokio-fs/src/read_dir.rs b/tokio-fs/src/read_dir.rs new file mode 100644 index 000000000..3818c7102 --- /dev/null +++ b/tokio-fs/src/read_dir.rs @@ -0,0 +1,247 @@ +use std::ffi::OsString; +use std::fs::{self, DirEntry as StdDirEntry, ReadDir as StdReadDir, FileType, Metadata}; +use std::io; +#[cfg(unix)] +use std::os::unix::fs::DirEntryExt; +use std::path::{Path, PathBuf}; + +use futures::{Future, Poll, Stream}; + +/// Returns a stream over the entries within a directory. +/// +/// This is an async version of [`std::fs::read_dir`][std] +/// +/// [std]: https://doc.rust-lang.org/std/fs/fn.read_dir.html +pub fn read_dir

(path: P) -> ReadDirFuture

+where + P: AsRef + Send + 'static, +{ + ReadDirFuture::new(path) +} + +/// Future returned by `read_dir`. +#[derive(Debug)] +pub struct ReadDirFuture

+where + P: AsRef + Send + 'static, +{ + path: P, +} + +impl

ReadDirFuture

+where + P: AsRef + Send + 'static +{ + fn new(path: P) -> ReadDirFuture

{ + ReadDirFuture { + path: path, + } + } +} + +impl

Future for ReadDirFuture

+where + P: AsRef + Send + 'static, +{ + type Item = ReadDir; + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| Ok(ReadDir(fs::read_dir(&self.path)?))) + } +} + +/// Stream of the entries in a directory. +/// +/// This stream is returned from the [`read_dir`] function of this module and +/// will yield instances of [`DirEntry`]. Through a [`DirEntry`] +/// information like the entry's path and possibly other metadata can be +/// learned. +/// +/// # Errors +/// +/// This [`Stream`] will return an [`Err`] if there's some sort of intermittent +/// IO error during iteration. +/// +/// [`read_dir`]: fn.read_dir.html +/// [`DirEntry`]: struct.DirEntry.html +/// [`Stream`]: ../futures/stream/trait.Stream.html +/// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err +#[derive(Debug)] +pub struct ReadDir(StdReadDir); + +impl Stream for ReadDir { + type Item = DirEntry; + type Error = io::Error; + + fn poll(&mut self) -> Poll, Self::Error> { + ::blocking_io(|| { + match self.0.next() { + Some(Err(err)) => Err(err), + Some(Ok(item)) => Ok(Some(DirEntry(item))), + None => Ok(None) + } + }) + } +} + +/// Entries returned by the [`ReadDir`] stream. +/// +/// [`ReadDir`]: struct.ReadDir.html +/// +/// This is a specialized version of [`std::fs::DirEntry`][std] for usage from the +/// Tokio runtime. +/// +/// An instance of `DirEntry` represents an entry inside of a directory on the +/// filesystem. Each entry can be inspected via methods to learn about the full +/// path or possibly other metadata through per-platform extension traits. +/// +/// [std]: https://doc.rust-lang.org/std/fs/struct.DirEntry.html +#[derive(Debug)] +pub struct DirEntry(StdDirEntry); + +impl DirEntry { + /// Destructures the `tokio_fs::DirEntry` into a [`std::fs::DirEntry`][std]. + /// + /// [std]: https://doc.rust-lang.org/std/fs/struct.DirEntry.html + pub fn into_std(self) -> StdDirEntry { + self.0 + } + + /// Returns the full path to the file that this entry represents. + /// + /// The full path is created by joining the original path to `read_dir` + /// with the filename of this entry. + /// + /// # Examples + /// + /// ``` + /// # extern crate futures; + /// # extern crate tokio; + /// # extern crate tokio_fs; + /// use futures::{Future, Stream}; + /// + /// fn main() { + /// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| { + /// println!("{:?}", dir.path()); + /// Ok(()) + /// }).map_err(|err| { eprintln!("Error: {:?}", err); () }); + /// tokio::run(fut); + /// } + /// ``` + /// + /// This prints output like: + /// + /// ```text + /// "./whatever.txt" + /// "./foo.html" + /// "./hello_world.rs" + /// ``` + /// + /// The exact text, of course, depends on what files you have in `.`. + pub fn path(&self) -> PathBuf { + self.0.path() + } + + /// Returns the bare file name of this directory entry without any other + /// leading path component. + /// + /// # Examples + /// + /// ``` + /// # extern crate futures; + /// # extern crate tokio; + /// # extern crate tokio_fs; + /// use futures::{Future, Stream}; + /// + /// fn main() { + /// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| { + /// // Here, `dir` is a `DirEntry`. + /// println!("{:?}", dir.file_name()); + /// Ok(()) + /// }).map_err(|err| { eprintln!("Error: {:?}", err); () }); + /// tokio::run(fut); + /// } + /// ``` + pub fn file_name(&self) -> OsString { + self.0.file_name() + } + + /// Return the metadata for the file that this entry points at. + /// + /// This function will not traverse symlinks if this entry points at a + /// symlink. + /// + /// # Platform-specific behavior + /// + /// On Windows this function is cheap to call (no extra system calls + /// needed), but on Unix platforms this function is the equivalent of + /// calling `symlink_metadata` on the path. + /// + /// # Examples + /// + /// ``` + /// # extern crate futures; + /// # extern crate tokio; + /// # extern crate tokio_fs; + /// use futures::{Future, Stream}; + /// use futures::future::poll_fn; + /// + /// fn main() { + /// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| { + /// // Here, `dir` is a `DirEntry`. + /// let path = dir.path(); + /// poll_fn(move || dir.poll_metadata()).map(move |metadata| { + /// println!("{:?}: {:?}", path, metadata.permissions()); + /// }) + /// }).map_err(|err| { eprintln!("Error: {:?}", err); () }); + /// tokio::run(fut); + /// } + /// ``` + pub fn poll_metadata(&self) -> Poll { + ::blocking_io(|| self.0.metadata()) + } + + /// Return the file type for the file that this entry points at. + /// + /// This function will not traverse symlinks if this entry points at a + /// symlink. + /// + /// # Platform-specific behavior + /// + /// On Windows and most Unix platforms this function is free (no extra + /// system calls needed), but some Unix platforms may require the equivalent + /// call to `symlink_metadata` to learn about the target file type. + /// + /// # Examples + /// + /// ``` + /// # extern crate futures; + /// # extern crate tokio; + /// # extern crate tokio_fs; + /// use futures::{Future, Stream}; + /// use futures::future::poll_fn; + /// + /// fn main() { + /// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| { + /// // Here, `dir` is a `DirEntry`. + /// let path = dir.path(); + /// poll_fn(move || dir.poll_file_type()).map(move |file_type| { + /// // Now let's show our entry's file type! + /// println!("{:?}: {:?}", path, file_type); + /// }) + /// }).map_err(|err| { eprintln!("Error: {:?}", err); () }); + /// tokio::run(fut); + /// } + /// ``` + pub fn poll_file_type(&self) -> Poll { + ::blocking_io(|| self.0.file_type()) + } +} + +#[cfg(unix)] +impl DirEntryExt for DirEntry { + fn ino(&self) -> u64 { + self.0.ino() + } +} diff --git a/tokio-fs/src/read_link.rs b/tokio-fs/src/read_link.rs new file mode 100644 index 000000000..5e5bf2a30 --- /dev/null +++ b/tokio-fs/src/read_link.rs @@ -0,0 +1,46 @@ +use std::fs; +use std::io; +use std::path::{Path, PathBuf}; + +use futures::{Future, Poll}; + +/// Reads a symbolic link, returning the file that the link points to. +/// +/// This is an async version of [`std::fs::read_link`][std] +/// +/// [std]: https://doc.rust-lang.org/std/fs/fn.read_link.html +pub fn read_link>(path: P) -> ReadLinkFuture

{ + ReadLinkFuture::new(path) +} + +/// Future returned by `read_link`. +#[derive(Debug)] +pub struct ReadLinkFuture

+where + P: AsRef +{ + path: P, +} + +impl

ReadLinkFuture

+where + P: AsRef +{ + fn new(path: P) -> ReadLinkFuture

{ + ReadLinkFuture { + path: path, + } + } +} + +impl

Future for ReadLinkFuture

+where + P: AsRef +{ + type Item = PathBuf; + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::read_link(&self.path) ) + } +} diff --git a/tokio-fs/src/remove_dir.rs b/tokio-fs/src/remove_dir.rs new file mode 100644 index 000000000..5aa73bfb5 --- /dev/null +++ b/tokio-fs/src/remove_dir.rs @@ -0,0 +1,46 @@ +use std::fs; +use std::io; +use std::path::Path; + +use futures::{Future, Poll}; + +/// Removes an existing, empty directory. +/// +/// This is an async version of [`std::fs::remove_dir`][std] +/// +/// [std]: https://doc.rust-lang.org/std/fs/fn.remove_dir.html +pub fn remove_dir>(path: P) -> RemoveDirFuture

{ + RemoveDirFuture::new(path) +} + +/// Future returned by `remove_dir`. +#[derive(Debug)] +pub struct RemoveDirFuture

+where + P: AsRef +{ + path: P, +} + +impl

RemoveDirFuture

+where + P: AsRef +{ + fn new(path: P) -> RemoveDirFuture

{ + RemoveDirFuture { + path: path, + } + } +} + +impl

Future for RemoveDirFuture

+where + P: AsRef +{ + type Item = (); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::remove_dir(&self.path) ) + } +} diff --git a/tokio-fs/src/remove_file.rs b/tokio-fs/src/remove_file.rs new file mode 100644 index 000000000..f61741857 --- /dev/null +++ b/tokio-fs/src/remove_file.rs @@ -0,0 +1,50 @@ +use std::fs; +use std::io; +use std::path::Path; + +use futures::{Future, Poll}; + +/// Removes a file from the filesystem. +/// +/// Note that there is no +/// guarantee that the file is immediately deleted (e.g. depending on +/// platform, other open file descriptors may prevent immediate removal). +/// +/// This is an async version of [`std::fs::remove_file`][std] +/// +/// [std]: https://doc.rust-lang.org/std/fs/fn.remove_file.html +pub fn remove_file>(path: P) -> RemoveFileFuture

{ + RemoveFileFuture::new(path) +} + +/// Future returned by `remove_file`. +#[derive(Debug)] +pub struct RemoveFileFuture

+where + P: AsRef +{ + path: P, +} + +impl

RemoveFileFuture

+where + P: AsRef +{ + fn new(path: P) -> RemoveFileFuture

{ + RemoveFileFuture { + path: path, + } + } +} + +impl

Future for RemoveFileFuture

+where + P: AsRef +{ + type Item = (); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::remove_file(&self.path) ) + } +} diff --git a/tokio-fs/src/rename.rs b/tokio-fs/src/rename.rs new file mode 100644 index 000000000..210f53bb5 --- /dev/null +++ b/tokio-fs/src/rename.rs @@ -0,0 +1,54 @@ +use std::fs; +use std::io; +use std::path::Path; + +use futures::{Future, Poll}; + +/// Rename a file or directory to a new name, replacing the original file if +/// `to` already exists. +/// +/// This will not work if the new name is on a different mount point. +/// +/// This is an async version of [`std::fs::rename`][std] +/// +/// [std]: https://doc.rust-lang.org/std/fs/fn.rename.html +pub fn rename, Q: AsRef>(from: P, to: Q) -> RenameFuture { + RenameFuture::new(from, to) +} + +/// Future returned by `rename`. +#[derive(Debug)] +pub struct RenameFuture +where + P: AsRef, + Q: AsRef +{ + from: P, + to: Q, +} + +impl RenameFuture +where + P: AsRef, + Q: AsRef +{ + fn new(from: P, to: Q) -> RenameFuture { + RenameFuture { + from: from, + to: to, + } + } +} + +impl Future for RenameFuture +where + P: AsRef, + Q: AsRef +{ + type Item = (); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::rename(&self.from, &self.to) ) + } +} diff --git a/tokio-fs/src/set_permissions.rs b/tokio-fs/src/set_permissions.rs new file mode 100644 index 000000000..a85044862 --- /dev/null +++ b/tokio-fs/src/set_permissions.rs @@ -0,0 +1,48 @@ +use std::fs; +use std::io; +use std::path::Path; + +use futures::{Future, Poll}; + +/// Changes the permissions found on a file or a directory. +/// +/// This is an async version of [`std::fs::set_permissions`][std] +/// +/// [std]: https://doc.rust-lang.org/std/fs/fn.set_permissions.html +pub fn set_permissions>(path: P, perm: fs::Permissions) -> SetPermissionsFuture

{ + SetPermissionsFuture::new(path, perm) +} + +/// Future returned by `set_permissions`. +#[derive(Debug)] +pub struct SetPermissionsFuture

+where + P: AsRef +{ + path: P, + perm: fs::Permissions, +} + +impl

SetPermissionsFuture

+where + P: AsRef +{ + fn new(path: P, perm: fs::Permissions) -> SetPermissionsFuture

{ + SetPermissionsFuture { + path: path, + perm: perm, + } + } +} + +impl

Future for SetPermissionsFuture

+where + P: AsRef +{ + type Item = (); + type Error = io::Error; + + fn poll(&mut self) -> Poll { + ::blocking_io(|| fs::set_permissions(&self.path, self.perm.clone()) ) + } +} diff --git a/tokio-fs/src/symlink_metadata.rs b/tokio-fs/src/symlink_metadata.rs new file mode 100644 index 000000000..db02769e2 --- /dev/null +++ b/tokio-fs/src/symlink_metadata.rs @@ -0,0 +1,49 @@ +use super::blocking_io; + +use futures::{Future, Poll}; + +use std::fs::{self, Metadata}; +use std::io; +use std::path::Path; + +/// Queries the file system metadata for a path. +/// +/// This is an async version of [`std::fs::symlink_metadata`][std] +/// +/// [std]: https://doc.rust-lang.org/std/fs/fn.symlink_metadata.html +pub fn symlink_metadata

(path: P) -> SymlinkMetadataFuture

+where + P: AsRef + Send + 'static, +{ + SymlinkMetadataFuture::new(path) +} + +/// Future returned by `symlink_metadata`. +#[derive(Debug)] +pub struct SymlinkMetadataFuture

+where + P: AsRef + Send + 'static, +{ + path: P, +} + +impl

SymlinkMetadataFuture

+where + P: AsRef + Send + 'static, +{ + pub(crate) fn new(path: P) -> Self { + Self { path } + } +} + +impl

Future for SymlinkMetadataFuture

+where + P: AsRef + Send + 'static, +{ + type Item = Metadata; + type Error = io::Error; + + fn poll(&mut self) -> Poll { + blocking_io(|| fs::symlink_metadata(&self.path)) + } +}