summaryrefslogtreecommitdiffstats
path: root/third_party/rust/tokio-fs/src/file
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/tokio-fs/src/file')
-rw-r--r--third_party/rust/tokio-fs/src/file/create.rs37
-rw-r--r--third_party/rust/tokio-fs/src/file/metadata.rs39
-rw-r--r--third_party/rust/tokio-fs/src/file/mod.rs243
-rw-r--r--third_party/rust/tokio-fs/src/file/open.rs38
-rw-r--r--third_party/rust/tokio-fs/src/file/open_options.rs103
-rw-r--r--third_party/rust/tokio-fs/src/file/seek.rs37
6 files changed, 497 insertions, 0 deletions
diff --git a/third_party/rust/tokio-fs/src/file/create.rs b/third_party/rust/tokio-fs/src/file/create.rs
new file mode 100644
index 0000000000..4027418563
--- /dev/null
+++ b/third_party/rust/tokio-fs/src/file/create.rs
@@ -0,0 +1,37 @@
+use super::File;
+
+use futures::{Future, Poll};
+
+use std::fs::File as StdFile;
+use std::io;
+use std::path::Path;
+
+/// Future returned by `File::create` and resolves to a `File` instance.
+#[derive(Debug)]
+pub struct CreateFuture<P> {
+ path: P,
+}
+
+impl<P> CreateFuture<P>
+where P: AsRef<Path> + Send + 'static,
+{
+ pub(crate) fn new(path: P) -> Self {
+ CreateFuture { path }
+ }
+}
+
+impl<P> Future for CreateFuture<P>
+where P: AsRef<Path> + Send + 'static,
+{
+ type Item = File;
+ type Error = io::Error;
+
+ fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
+ let std = try_ready!(::blocking_io(|| {
+ StdFile::create(&self.path)
+ }));
+
+ let file = File::from_std(std);
+ Ok(file.into())
+ }
+}
diff --git a/third_party/rust/tokio-fs/src/file/metadata.rs b/third_party/rust/tokio-fs/src/file/metadata.rs
new file mode 100644
index 0000000000..b55ca103c1
--- /dev/null
+++ b/third_party/rust/tokio-fs/src/file/metadata.rs
@@ -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())
+ }
+}
diff --git a/third_party/rust/tokio-fs/src/file/mod.rs b/third_party/rust/tokio-fs/src/file/mod.rs
new file mode 100644
index 0000000000..c3ae431121
--- /dev/null
+++ b/third_party/rust/tokio-fs/src/file/mod.rs
@@ -0,0 +1,243 @@
+//! Types for working with [`File`].
+//!
+//! [`File`]: file/struct.File.html
+
+mod create;
+mod metadata;
+mod open;
+mod open_options;
+mod seek;
+
+pub use self::create::CreateFuture;
+pub use self::metadata::MetadataFuture;
+pub use self::open::OpenFuture;
+pub use self::open_options::OpenOptions;
+pub use self::seek::SeekFuture;
+
+use tokio_io::{AsyncRead, AsyncWrite};
+
+use futures::Poll;
+
+use std::fs::{File as StdFile, Metadata, Permissions};
+use std::io::{self, Read, Write, Seek};
+use std::path::Path;
+
+/// A reference to an open file on the filesystem.
+///
+/// This is a specialized version of [`std::fs::File`][std] for usage from the
+/// Tokio runtime.
+///
+/// An instance of a `File` can be read and/or written depending on what options
+/// it was opened with. Files also implement Seek to alter the logical cursor
+/// that the file contains internally.
+///
+/// Files are automatically closed when they go out of scope.
+///
+/// [std]: https://doc.rust-lang.org/std/fs/struct.File.html
+#[derive(Debug)]
+pub struct File {
+ std: Option<StdFile>,
+}
+
+impl File {
+ /// Attempts to open a file in read-only mode.
+ ///
+ /// See [`OpenOptions`] for more details.
+ ///
+ /// [`OpenOptions`]: struct.OpenOptions.html
+ ///
+ /// # Errors
+ ///
+ /// `OpenFuture` results in an error if called from outside of the Tokio
+ /// runtime or if the underlying [`open`] call results in an error.
+ ///
+ /// [`open`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.open
+ pub fn open<P>(path: P) -> OpenFuture<P>
+ where P: AsRef<Path> + Send + 'static,
+ {
+ OpenOptions::new().read(true).open(path)
+ }
+
+ /// Opens a file in write-only mode.
+ ///
+ /// This function will create a file if it does not exist, and will truncate
+ /// it if it does.
+ ///
+ /// See [`OpenOptions`] for more details.
+ ///
+ /// [`OpenOptions`]: struct.OpenOptions.html
+ ///
+ /// # Errors
+ ///
+ /// `CreateFuture` results in an error if called from outside of the Tokio
+ /// runtime or if the underlying [`create`] call results in an error.
+ ///
+ /// [`create`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.create
+ pub fn create<P>(path: P) -> CreateFuture<P>
+ where P: AsRef<Path> + Send + 'static,
+ {
+ CreateFuture::new(path)
+ }
+
+ /// Convert a [`std::fs::File`][std] to a `tokio_fs::File`.
+ ///
+ /// [std]: https://doc.rust-lang.org/std/fs/struct.File.html
+ pub(crate) fn from_std(std: StdFile) -> File {
+ File { std: Some(std) }
+ }
+
+ /// Seek to an offset, in bytes, in a stream.
+ ///
+ /// A seek beyond the end of a stream is allowed, but implementation
+ /// defined.
+ ///
+ /// If the seek operation completed successfully, this method returns the
+ /// new position from the start of the stream. That position can be used
+ /// later with `SeekFrom::Start`.
+ ///
+ /// # Errors
+ ///
+ /// Seeking to a negative offset is considered an error.
+ pub fn poll_seek(&mut self, pos: io::SeekFrom) -> Poll<u64, io::Error> {
+ ::blocking_io(|| self.std().seek(pos))
+ }
+
+ /// Seek to an offset, in bytes, in a stream.
+ ///
+ /// Similar to `poll_seek`, but returning a `Future`.
+ ///
+ /// This method consumes the `File` and returns it back when the future
+ /// completes.
+ pub fn seek(self, pos: io::SeekFrom) -> SeekFuture {
+ SeekFuture::new(self, pos)
+ }
+
+ /// Attempts to sync all OS-internal metadata to disk.
+ ///
+ /// This function will attempt to ensure that all in-core data reaches the
+ /// filesystem before returning.
+ pub fn poll_sync_all(&mut self) -> Poll<(), io::Error> {
+ ::blocking_io(|| self.std().sync_all())
+ }
+
+ /// This function is similar to `poll_sync_all`, except that it may not
+ /// synchronize file metadata to the filesystem.
+ ///
+ /// This is intended for use cases that must synchronize content, but don't
+ /// need the metadata on disk. The goal of this method is to reduce disk
+ /// operations.
+ ///
+ /// Note that some platforms may simply implement this in terms of `poll_sync_all`.
+ pub fn poll_sync_data(&mut self) -> Poll<(), io::Error> {
+ ::blocking_io(|| self.std().sync_data())
+ }
+
+ /// Truncates or extends the underlying file, updating the size of this file to become size.
+ ///
+ /// If the size is less than the current file's size, then the file will be
+ /// shrunk. If it is greater than the current file's size, then the file
+ /// will be extended to size and have all of the intermediate data filled in
+ /// with 0s.
+ ///
+ /// # Errors
+ ///
+ /// This function will return an error if the file is not opened for
+ /// writing.
+ pub fn poll_set_len(&mut self, size: u64) -> Poll<(), io::Error> {
+ ::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())
+ }
+
+ /// 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.
+ pub fn poll_try_clone(&mut self) -> Poll<File, io::Error> {
+ ::blocking_io(|| {
+ let std = self.std().try_clone()?;
+ Ok(File::from_std(std))
+ })
+ }
+
+ /// Changes the permissions on the underlying file.
+ ///
+ /// # Platform-specific behavior
+ ///
+ /// This function currently corresponds to the `fchmod` function on Unix and
+ /// the `SetFileInformationByHandle` function on Windows. Note that, this
+ /// [may change in the future][changes].
+ ///
+ /// [changes]: https://doc.rust-lang.org/std/io/index.html#platform-specific-behavior
+ ///
+ /// # Errors
+ ///
+ /// This function will return an error if the user lacks permission change
+ /// attributes on the underlying file. It may also return an error in other
+ /// os-specific unspecified cases.
+ pub fn poll_set_permissions(&mut self, perm: Permissions) -> Poll<(), io::Error> {
+ ::blocking_io(|| self.std().set_permissions(perm))
+ }
+
+ /// Destructures the `tokio_fs::File` into a [`std::fs::File`][std].
+ ///
+ /// # Panics
+ ///
+ /// This function will panic if `shutdown` has been called.
+ ///
+ /// [std]: https://doc.rust-lang.org/std/fs/struct.File.html
+ pub fn into_std(mut self) -> StdFile {
+ self.std.take().expect("`File` instance already shutdown")
+ }
+
+ fn std(&mut self) -> &mut StdFile {
+ self.std.as_mut().expect("`File` instance already shutdown")
+ }
+}
+
+impl Read for File {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ ::would_block(|| self.std().read(buf))
+ }
+}
+
+impl AsyncRead for File {
+ unsafe fn prepare_uninitialized_buffer(&self, _: &mut [u8]) -> bool {
+ false
+ }
+}
+
+impl Write for File {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ ::would_block(|| self.std().write(buf))
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ ::would_block(|| self.std().flush())
+ }
+}
+
+impl AsyncWrite for File {
+ fn shutdown(&mut self) -> Poll<(), io::Error> {
+ ::blocking_io(|| {
+ self.std = None;
+ Ok(())
+ })
+ }
+}
+
+impl Drop for File {
+ fn drop(&mut self) {
+ if let Some(_std) = self.std.take() {
+ // This is probably fine as closing a file *shouldn't* be a blocking
+ // operation. That said, ideally `shutdown` is called first.
+ }
+ }
+}
diff --git a/third_party/rust/tokio-fs/src/file/open.rs b/third_party/rust/tokio-fs/src/file/open.rs
new file mode 100644
index 0000000000..197ec237af
--- /dev/null
+++ b/third_party/rust/tokio-fs/src/file/open.rs
@@ -0,0 +1,38 @@
+use super::File;
+
+use futures::{Future, Poll};
+
+use std::fs::OpenOptions as StdOpenOptions;
+use std::io;
+use std::path::Path;
+
+/// Future returned by `File::open` and resolves to a `File` instance.
+#[derive(Debug)]
+pub struct OpenFuture<P> {
+ options: StdOpenOptions,
+ path: P,
+}
+
+impl<P> OpenFuture<P>
+where P: AsRef<Path> + Send + 'static,
+{
+ pub(crate) fn new(options: StdOpenOptions, path: P) -> Self {
+ OpenFuture { options, path }
+ }
+}
+
+impl<P> Future for OpenFuture<P>
+where P: AsRef<Path> + Send + 'static,
+{
+ type Item = File;
+ type Error = io::Error;
+
+ fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
+ let std = try_ready!(::blocking_io(|| {
+ self.options.open(&self.path)
+ }));
+
+ let file = File::from_std(std);
+ Ok(file.into())
+ }
+}
diff --git a/third_party/rust/tokio-fs/src/file/open_options.rs b/third_party/rust/tokio-fs/src/file/open_options.rs
new file mode 100644
index 0000000000..99cc71c5b0
--- /dev/null
+++ b/third_party/rust/tokio-fs/src/file/open_options.rs
@@ -0,0 +1,103 @@
+use super::OpenFuture;
+
+use std::convert::From;
+use std::fs::OpenOptions as StdOpenOptions;
+use std::path::Path;
+
+/// Options and flags which can be used to configure how a file is opened.
+///
+/// This is a specialized version of [`std::fs::OpenOptions`] for usage from
+/// the Tokio runtime.
+///
+/// `From<std::fs::OpenOptions>` is implemented for more advanced configuration
+/// than the methods provided here.
+///
+/// [`std::fs::OpenOptions`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html
+#[derive(Clone, Debug)]
+pub struct OpenOptions(StdOpenOptions);
+
+impl OpenOptions {
+ /// Creates a blank new set of options ready for configuration.
+ ///
+ /// All options are initially set to `false`.
+ ///
+ /// # Examples
+ ///
+ /// ```ignore
+ /// use tokio::fs::OpenOptions;
+ ///
+ /// let mut options = OpenOptions::new();
+ /// let future = options.read(true).open("foo.txt");
+ /// ```
+ pub fn new() -> OpenOptions {
+ OpenOptions(StdOpenOptions::new())
+ }
+
+ /// See the underlying [`read`] call for details.
+ ///
+ /// [`read`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.read
+ pub fn read(&mut self, read: bool) -> &mut OpenOptions {
+ self.0.read(read);
+ self
+ }
+
+ /// See the underlying [`write`] call for details.
+ ///
+ /// [`write`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.write
+ pub fn write(&mut self, write: bool) -> &mut OpenOptions {
+ self.0.write(write);
+ self
+ }
+
+ /// See the underlying [`append`] call for details.
+ ///
+ /// [`append`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.append
+ pub fn append(&mut self, append: bool) -> &mut OpenOptions {
+ self.0.append(append);
+ self
+ }
+
+ /// See the underlying [`truncate`] call for details.
+ ///
+ /// [`truncate`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.truncate
+ pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
+ self.0.truncate(truncate);
+ self
+ }
+
+ /// See the underlying [`create`] call for details.
+ ///
+ /// [`create`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create
+ pub fn create(&mut self, create: bool) -> &mut OpenOptions {
+ self.0.create(create);
+ self
+ }
+
+ /// See the underlying [`create_new`] call for details.
+ ///
+ /// [`create_new`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create_new
+ pub fn create_new(&mut self, create_new: bool) -> &mut OpenOptions {
+ self.0.create_new(create_new);
+ self
+ }
+
+ /// Opens a file at `path` with the options specified by `self`.
+ ///
+ /// # Errors
+ ///
+ /// `OpenOptionsFuture` results in an error if called from outside of the
+ /// Tokio runtime or if the underlying [`open`] call results in an error.
+ ///
+ /// [`open`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.open
+ pub fn open<P>(&self, path: P) -> OpenFuture<P>
+ where P: AsRef<Path> + Send + 'static
+ {
+ OpenFuture::new(self.0.clone(), path)
+ }
+}
+
+impl From<StdOpenOptions> for OpenOptions {
+ fn from(options: StdOpenOptions) -> OpenOptions {
+ OpenOptions(options)
+ }
+}
diff --git a/third_party/rust/tokio-fs/src/file/seek.rs b/third_party/rust/tokio-fs/src/file/seek.rs
new file mode 100644
index 0000000000..0765d3db90
--- /dev/null
+++ b/third_party/rust/tokio-fs/src/file/seek.rs
@@ -0,0 +1,37 @@
+use super::File;
+
+use futures::{Future, Poll};
+
+use std::io;
+
+/// Future returned by `File::seek`.
+#[derive(Debug)]
+pub struct SeekFuture {
+ inner: Option<File>,
+ pos: io::SeekFrom,
+}
+
+impl SeekFuture {
+ pub(crate) fn new(file: File, pos: io::SeekFrom) -> Self {
+ Self {
+ pos,
+ inner: Some(file),
+ }
+ }
+}
+
+impl Future for SeekFuture {
+ type Item = (File, u64);
+ type Error = io::Error;
+
+ fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
+ let pos = try_ready!(
+ self.inner
+ .as_mut()
+ .expect("Cannot poll `SeekFuture` after it resolves")
+ .poll_seek(self.pos)
+ );
+ let inner = self.inner.take().unwrap();
+ Ok((inner, pos).into())
+ }
+}