diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/fs-err/src/tokio | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/fs-err/src/tokio')
-rw-r--r-- | third_party/rust/fs-err/src/tokio/dir_builder.rs | 54 | ||||
-rw-r--r-- | third_party/rust/fs-err/src/tokio/file.rs | 243 | ||||
-rw-r--r-- | third_party/rust/fs-err/src/tokio/mod.rs | 189 | ||||
-rw-r--r-- | third_party/rust/fs-err/src/tokio/open_options.rs | 109 | ||||
-rw-r--r-- | third_party/rust/fs-err/src/tokio/read_dir.rs | 94 |
5 files changed, 689 insertions, 0 deletions
diff --git a/third_party/rust/fs-err/src/tokio/dir_builder.rs b/third_party/rust/fs-err/src/tokio/dir_builder.rs new file mode 100644 index 0000000000..0615999ee1 --- /dev/null +++ b/third_party/rust/fs-err/src/tokio/dir_builder.rs @@ -0,0 +1,54 @@ +use crate::errors::{Error, ErrorKind};
+use std::io;
+use std::path::Path;
+
+/// A builder for creating directories in various manners.
+///
+/// This is a wrapper around [`tokio::fs::DirBuilder`].
+#[derive(Debug, Default)]
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub struct DirBuilder {
+ inner: tokio::fs::DirBuilder,
+}
+
+impl DirBuilder {
+ /// Creates a new set of options with default mode/security settings for all
+ /// platforms and also non-recursive.
+ ///
+ /// This is a wrapper version of [`tokio::fs::DirBuilder::new`]
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use fs_err::tokio::DirBuilder;
+ ///
+ /// let builder = DirBuilder::new();
+ /// ```
+ pub fn new() -> Self {
+ Default::default()
+ }
+
+ /// Wrapper around [`tokio::fs::DirBuilder::recursive`].
+ pub fn recursive(&mut self, recursive: bool) -> &mut Self {
+ self.inner.recursive(recursive);
+ self
+ }
+
+ /// Wrapper around [`tokio::fs::DirBuilder::create`].
+ pub async fn create(&self, path: impl AsRef<Path>) -> io::Result<()> {
+ let path = path.as_ref();
+ self.inner
+ .create(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::CreateDir, path))
+ }
+}
+
+#[cfg(unix)]
+impl DirBuilder {
+ /// Wrapper around [`tokio::fs::DirBuilder::mode`].
+ pub fn mode(&mut self, mode: u32) -> &mut Self {
+ self.inner.mode(mode);
+ self
+ }
+}
diff --git a/third_party/rust/fs-err/src/tokio/file.rs b/third_party/rust/fs-err/src/tokio/file.rs new file mode 100644 index 0000000000..c0dac4ca47 --- /dev/null +++ b/third_party/rust/fs-err/src/tokio/file.rs @@ -0,0 +1,243 @@ +use crate::errors::{Error, ErrorKind};
+use std::fs::{Metadata, Permissions};
+use std::io;
+use std::io::{IoSlice, SeekFrom};
+use std::path::{Path, PathBuf};
+use std::pin::Pin;
+use std::task::{ready, Context, Poll};
+use tokio::fs;
+use tokio::fs::File as TokioFile;
+use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite, ReadBuf};
+
+/// Wrapper around [`tokio::fs::File`] which adds more helpful
+/// information to all errors.
+#[derive(Debug)]
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub struct File {
+ tokio: fs::File,
+ path: PathBuf,
+}
+
+impl File {
+ /// Wrapper for [`tokio::fs::File::open`].
+ pub async fn open(path: impl Into<PathBuf>) -> io::Result<File> {
+ let path = path.into();
+ let f = TokioFile::open(&path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::OpenFile, &path))?;
+ Ok(File::from_parts(f, path))
+ }
+
+ /// Wrapper for [`tokio::fs::File::create`].
+ pub async fn create(path: impl Into<PathBuf>) -> io::Result<File> {
+ let path = path.into();
+ match TokioFile::create(&path).await {
+ Ok(f) => Ok(File::from_parts(f, path)),
+ Err(err) => Err(Error::build(err, ErrorKind::CreateFile, &path)),
+ }
+ }
+
+ /// Wrapper for [`tokio::fs::File::from_std`].
+ pub fn from_std(std: crate::File) -> File {
+ let (std, path) = std.into_parts();
+ File::from_parts(TokioFile::from_std(std), path)
+ }
+
+ /// Wrapper for [`tokio::fs::File::sync_all`].
+ pub async fn sync_all(&self) -> io::Result<()> {
+ self.tokio
+ .sync_all()
+ .await
+ .map_err(|err| self.error(err, ErrorKind::SyncFile))
+ }
+
+ /// Wrapper for [`tokio::fs::File::sync_data`].
+ pub async fn sync_data(&self) -> io::Result<()> {
+ self.tokio
+ .sync_data()
+ .await
+ .map_err(|err| self.error(err, ErrorKind::SyncFile))
+ }
+
+ /// Wrapper for [`tokio::fs::File::set_len`].
+ pub async fn set_len(&self, size: u64) -> io::Result<()> {
+ self.tokio
+ .set_len(size)
+ .await
+ .map_err(|err| self.error(err, ErrorKind::SetLen))
+ }
+
+ /// Wrapper for [`tokio::fs::File::metadata`].
+ pub async fn metadata(&self) -> io::Result<Metadata> {
+ self.tokio
+ .metadata()
+ .await
+ .map_err(|err| self.error(err, ErrorKind::Metadata))
+ }
+
+ /// Wrapper for [`tokio::fs::File::try_clone`].
+ pub async fn try_clone(&self) -> io::Result<File> {
+ match self.tokio.try_clone().await {
+ Ok(file) => Ok(File::from_parts(file, self.path.clone())),
+ Err(err) => Err(self.error(err, ErrorKind::Clone)),
+ }
+ }
+
+ /// Wrapper for [`tokio::fs::File::into_std`].
+ pub async fn into_std(self) -> crate::File {
+ crate::File::from_parts(self.tokio.into_std().await, self.path)
+ }
+
+ /// Wrapper for [`tokio::fs::File::try_into_std`].
+ pub fn try_into_std(self) -> Result<crate::File, File> {
+ match self.tokio.try_into_std() {
+ Ok(f) => Ok(crate::File::from_parts(f, self.path)),
+ Err(f) => Err(File::from_parts(f, self.path)),
+ }
+ }
+
+ /// Wrapper for [`tokio::fs::File::set_permissions`].
+ pub async fn set_permissions(&self, perm: Permissions) -> io::Result<()> {
+ self.tokio
+ .set_permissions(perm)
+ .await
+ .map_err(|err| self.error(err, ErrorKind::SetPermissions))
+ }
+}
+
+/// Methods added by fs-err that are not available on
+/// [`tokio::fs::File`].
+impl File {
+ /// Creates a [`File`](struct.File.html) from a raw file and its path.
+ pub fn from_parts<P>(file: TokioFile, path: P) -> Self
+ where
+ P: Into<PathBuf>,
+ {
+ File {
+ tokio: file,
+ path: path.into(),
+ }
+ }
+
+ /// Extract the raw file and its path from this [`File`](struct.File.html).
+ pub fn into_parts(self) -> (TokioFile, PathBuf) {
+ (self.tokio, self.path)
+ }
+
+ /// Returns a reference to the underlying [`tokio::fs::File`].
+ pub fn file(&self) -> &TokioFile {
+ &self.tokio
+ }
+
+ /// Returns a mutable reference to the underlying [`tokio::fs::File`].
+ pub fn file_mut(&mut self) -> &mut TokioFile {
+ &mut self.tokio
+ }
+
+ /// Returns a reference to the path that this file was created with.
+ pub fn path(&self) -> &Path {
+ &self.path
+ }
+
+ /// Wrap the error in information specific to this `File` object.
+ fn error(&self, source: io::Error, kind: ErrorKind) -> io::Error {
+ Error::build(source, kind, &self.path)
+ }
+}
+
+impl From<crate::File> for File {
+ fn from(f: crate::File) -> Self {
+ let (f, path) = f.into_parts();
+ File::from_parts(f.into(), path)
+ }
+}
+
+impl From<File> for TokioFile {
+ fn from(f: File) -> Self {
+ f.into_parts().0
+ }
+}
+
+#[cfg(unix)]
+impl std::os::unix::io::AsRawFd for File {
+ fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
+ self.tokio.as_raw_fd()
+ }
+}
+
+#[cfg(windows)]
+impl std::os::windows::io::AsRawHandle for File {
+ fn as_raw_handle(&self) -> std::os::windows::io::RawHandle {
+ self.tokio.as_raw_handle()
+ }
+}
+
+impl AsyncRead for File {
+ fn poll_read(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ buf: &mut ReadBuf<'_>,
+ ) -> Poll<io::Result<()>> {
+ Poll::Ready(
+ ready!(Pin::new(&mut self.tokio).poll_read(cx, buf))
+ .map_err(|err| self.error(err, ErrorKind::Read)),
+ )
+ }
+}
+
+impl AsyncSeek for File {
+ fn start_seek(mut self: Pin<&mut Self>, position: SeekFrom) -> io::Result<()> {
+ Pin::new(&mut self.tokio)
+ .start_seek(position)
+ .map_err(|err| self.error(err, ErrorKind::Seek))
+ }
+
+ fn poll_complete(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<u64>> {
+ Poll::Ready(
+ ready!(Pin::new(&mut self.tokio).poll_complete(cx))
+ .map_err(|err| self.error(err, ErrorKind::Seek)),
+ )
+ }
+}
+
+impl AsyncWrite for File {
+ fn poll_write(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ buf: &[u8],
+ ) -> Poll<io::Result<usize>> {
+ Poll::Ready(
+ ready!(Pin::new(&mut self.tokio).poll_write(cx, buf))
+ .map_err(|err| self.error(err, ErrorKind::Write)),
+ )
+ }
+
+ fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
+ Poll::Ready(
+ ready!(Pin::new(&mut self.tokio).poll_flush(cx))
+ .map_err(|err| self.error(err, ErrorKind::Flush)),
+ )
+ }
+
+ fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
+ Poll::Ready(
+ ready!(Pin::new(&mut self.tokio).poll_shutdown(cx))
+ .map_err(|err| self.error(err, ErrorKind::Flush)),
+ )
+ }
+
+ fn poll_write_vectored(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ bufs: &[IoSlice<'_>],
+ ) -> Poll<io::Result<usize>> {
+ Poll::Ready(
+ ready!(Pin::new(&mut self.tokio).poll_write_vectored(cx, bufs))
+ .map_err(|err| self.error(err, ErrorKind::Write)),
+ )
+ }
+
+ fn is_write_vectored(&self) -> bool {
+ self.tokio.is_write_vectored()
+ }
+}
diff --git a/third_party/rust/fs-err/src/tokio/mod.rs b/third_party/rust/fs-err/src/tokio/mod.rs new file mode 100644 index 0000000000..bf4ac94ad2 --- /dev/null +++ b/third_party/rust/fs-err/src/tokio/mod.rs @@ -0,0 +1,189 @@ +//! Tokio-specific wrappers that use `fs_err` error messages.
+
+use crate::errors::{Error, ErrorKind, SourceDestError, SourceDestErrorKind};
+use std::fs::{Metadata, Permissions};
+use std::path::{Path, PathBuf};
+use tokio::io;
+mod dir_builder;
+mod file;
+mod open_options;
+mod read_dir;
+
+pub use self::open_options::OpenOptions;
+pub use self::read_dir::{read_dir, DirEntry, ReadDir};
+pub use dir_builder::DirBuilder;
+pub use file::File;
+
+/// Wrapper for [`tokio::fs::canonicalize`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn canonicalize(path: impl AsRef<Path>) -> io::Result<PathBuf> {
+ let path = path.as_ref();
+ tokio::fs::canonicalize(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::Canonicalize, path))
+}
+
+/// Wrapper for [`tokio::fs::copy`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn copy(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<u64, io::Error> {
+ let (from, to) = (from.as_ref(), to.as_ref());
+ tokio::fs::copy(from, to)
+ .await
+ .map_err(|err| SourceDestError::build(err, SourceDestErrorKind::Copy, from, to))
+}
+
+/// Wrapper for [`tokio::fs::create_dir`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn create_dir(path: impl AsRef<Path>) -> io::Result<()> {
+ let path = path.as_ref();
+ tokio::fs::create_dir(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::CreateDir, path))
+}
+
+/// Wrapper for [`tokio::fs::create_dir_all`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn create_dir_all(path: impl AsRef<Path>) -> io::Result<()> {
+ let path = path.as_ref();
+ tokio::fs::create_dir_all(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::CreateDir, path))
+}
+
+/// Wrapper for [`tokio::fs::hard_link`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
+ let (src, dst) = (src.as_ref(), dst.as_ref());
+ tokio::fs::hard_link(src, dst)
+ .await
+ .map_err(|err| SourceDestError::build(err, SourceDestErrorKind::HardLink, src, dst))
+}
+
+/// Wrapper for [`tokio::fs::metadata`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn metadata(path: impl AsRef<Path>) -> io::Result<Metadata> {
+ let path = path.as_ref();
+ tokio::fs::metadata(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::Metadata, path))
+}
+
+/// Wrapper for [`tokio::fs::read`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn read(path: impl AsRef<Path>) -> io::Result<Vec<u8>> {
+ let path = path.as_ref();
+ tokio::fs::read(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::Read, path))
+}
+
+/// Wrapper for [`tokio::fs::read_link`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn read_link(path: impl AsRef<Path>) -> io::Result<PathBuf> {
+ let path = path.as_ref();
+ tokio::fs::read_link(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::ReadLink, path))
+}
+
+/// Wrapper for [`tokio::fs::read_to_string`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn read_to_string(path: impl AsRef<Path>) -> io::Result<String> {
+ let path = path.as_ref();
+ tokio::fs::read_to_string(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::Read, path))
+}
+
+/// Wrapper for [`tokio::fs::remove_dir`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn remove_dir(path: impl AsRef<Path>) -> io::Result<()> {
+ let path = path.as_ref();
+ tokio::fs::remove_dir(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::RemoveDir, path))
+}
+
+/// Wrapper for [`tokio::fs::remove_dir_all`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn remove_dir_all(path: impl AsRef<Path>) -> io::Result<()> {
+ let path = path.as_ref();
+ tokio::fs::remove_dir_all(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::RemoveDir, path))
+}
+
+/// Wrapper for [`tokio::fs::remove_file`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn remove_file(path: impl AsRef<Path>) -> io::Result<()> {
+ let path = path.as_ref();
+ tokio::fs::remove_file(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::RemoveFile, path))
+}
+
+/// Wrapper for [`tokio::fs::rename`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn rename(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
+ let (from, to) = (from.as_ref(), to.as_ref());
+ tokio::fs::rename(from, to)
+ .await
+ .map_err(|err| SourceDestError::build(err, SourceDestErrorKind::Rename, from, to))
+}
+
+/// Wrapper for [`tokio::fs::set_permissions`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn set_permissions(path: impl AsRef<Path>, perm: Permissions) -> io::Result<()> {
+ let path = path.as_ref();
+ tokio::fs::set_permissions(path, perm)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::SetPermissions, path))
+}
+
+/// Wrapper for [`tokio::fs::symlink_metadata`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn symlink_metadata(path: impl AsRef<Path>) -> io::Result<Metadata> {
+ let path = path.as_ref();
+ tokio::fs::symlink_metadata(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::SymlinkMetadata, path))
+}
+
+/// Wrapper for [`tokio::fs::symlink`].
+#[cfg(unix)]
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn symlink(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
+ let (src, dst) = (src.as_ref(), dst.as_ref());
+ tokio::fs::symlink(src, dst)
+ .await
+ .map_err(|err| SourceDestError::build(err, SourceDestErrorKind::Symlink, src, dst))
+}
+
+/// Wrapper for [`tokio::fs::symlink_dir`].
+#[cfg(windows)]
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn symlink(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
+ let (src, dst) = (src.as_ref(), dst.as_ref());
+ tokio::fs::symlink_dir(src, dst)
+ .await
+ .map_err(|err| SourceDestError::build(err, SourceDestErrorKind::SymlinkDir, src, dst))
+}
+
+/// Wrapper for [`tokio::fs::symlink_file`].
+#[cfg(windows)]
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn symlink_file(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
+ let (src, dst) = (src.as_ref(), dst.as_ref());
+ tokio::fs::symlink_file(src, dst)
+ .await
+ .map_err(|err| SourceDestError::build(err, SourceDestErrorKind::SymlinkFile, src, dst))
+}
+
+/// Wrapper for [`tokio::fs::write`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> io::Result<()> {
+ let (path, contents) = (path.as_ref(), contents.as_ref());
+ tokio::fs::write(path, contents)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::Write, path))
+}
diff --git a/third_party/rust/fs-err/src/tokio/open_options.rs b/third_party/rust/fs-err/src/tokio/open_options.rs new file mode 100644 index 0000000000..6a2b5bf35d --- /dev/null +++ b/third_party/rust/fs-err/src/tokio/open_options.rs @@ -0,0 +1,109 @@ +use crate::errors::{Error, ErrorKind};
+use crate::tokio::File;
+use std::io;
+use std::path::Path;
+use tokio::fs::OpenOptions as TokioOpenOptions;
+
+/// Options and flags which can be used to configure how a file is opened.
+///
+/// This is a wrapper around [`tokio::fs::OpenOptions`].
+#[derive(Clone, Debug, Default)]
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub struct OpenOptions {
+ tokio: TokioOpenOptions,
+}
+
+impl OpenOptions {
+ /// Creates a blank new set of options ready for configuration.
+ ///
+ /// All options are initially set to `false`.
+ ///
+ /// This is a wrapped version of [`tokio::fs::OpenOptions::new`]
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// use fs_err::tokio::OpenOptions;
+ ///
+ /// let mut options = OpenOptions::new();
+ /// let future = options.read(true).open("foo.txt");
+ /// ```
+ pub fn new() -> OpenOptions {
+ OpenOptions {
+ tokio: TokioOpenOptions::new(),
+ }
+ }
+
+ /// Wrapper for [`tokio::fs::OpenOptions::read`].
+ pub fn read(&mut self, read: bool) -> &mut OpenOptions {
+ self.tokio.read(read);
+ self
+ }
+
+ /// Wrapper for [`tokio::fs::OpenOptions::write`].
+ pub fn write(&mut self, write: bool) -> &mut OpenOptions {
+ self.tokio.write(write);
+ self
+ }
+
+ /// Wrapper for [`tokio::fs::OpenOptions::append`].
+ pub fn append(&mut self, append: bool) -> &mut OpenOptions {
+ self.tokio.append(append);
+ self
+ }
+
+ /// Wrapper for [`tokio::fs::OpenOptions::truncate`].
+ pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
+ self.tokio.truncate(truncate);
+ self
+ }
+
+ /// Wrapper for [`tokio::fs::OpenOptions::create`].
+ pub fn create(&mut self, create: bool) -> &mut OpenOptions {
+ self.tokio.create(create);
+ self
+ }
+
+ /// Wrapper for [`tokio::fs::OpenOptions::create_new`].
+ pub fn create_new(&mut self, create_new: bool) -> &mut OpenOptions {
+ self.tokio.create_new(create_new);
+ self
+ }
+
+ /// Wrapper for [`tokio::fs::OpenOptions::open`].
+ pub async fn open(&self, path: impl AsRef<Path>) -> io::Result<File> {
+ let path = path.as_ref();
+ self.tokio
+ .open(path)
+ .await
+ .map(|f| File::from_parts(f, path))
+ .map_err(|err| Error::build(err, ErrorKind::OpenFile, path))
+ }
+}
+
+#[cfg(unix)]
+impl OpenOptions {
+ /// Wrapper for [`tokio::fs::OpenOptions::mode`].
+ pub fn mode(&mut self, mode: u32) -> &mut OpenOptions {
+ self.tokio.mode(mode);
+ self
+ }
+
+ /// Wrapper for [`tokio::fs::OpenOptions::custom_flags`].
+ pub fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
+ self.tokio.custom_flags(flags);
+ self
+ }
+}
+
+impl From<std::fs::OpenOptions> for OpenOptions {
+ fn from(std: std::fs::OpenOptions) -> Self {
+ OpenOptions { tokio: std.into() }
+ }
+}
+
+impl From<TokioOpenOptions> for OpenOptions {
+ fn from(tokio: TokioOpenOptions) -> Self {
+ OpenOptions { tokio }
+ }
+}
diff --git a/third_party/rust/fs-err/src/tokio/read_dir.rs b/third_party/rust/fs-err/src/tokio/read_dir.rs new file mode 100644 index 0000000000..2594edfa92 --- /dev/null +++ b/third_party/rust/fs-err/src/tokio/read_dir.rs @@ -0,0 +1,94 @@ +use crate::errors::{Error, ErrorKind};
+use std::ffi::OsString;
+use std::fs::{FileType, Metadata};
+use std::io;
+use std::path::{Path, PathBuf};
+use std::task::{ready, Context, Poll};
+use tokio::fs;
+
+/// Wrapper for [`tokio::fs::read_dir`].
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub async fn read_dir(path: impl AsRef<Path>) -> io::Result<ReadDir> {
+ let path = path.as_ref();
+ let tokio = fs::read_dir(path)
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::ReadDir, path))?;
+ Ok(ReadDir {
+ tokio,
+ path: path.to_owned(),
+ })
+}
+
+/// Reads the entries in a directory.
+///
+/// This is a wrapper around [`tokio::fs::ReadDir`].
+#[derive(Debug)]
+#[must_use = "streams do nothing unless polled"]
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub struct ReadDir {
+ tokio: fs::ReadDir,
+ path: PathBuf,
+}
+
+impl ReadDir {
+ /// Wrapper around [`tokio::fs::ReadDir::next_entry`].
+ pub async fn next_entry(&mut self) -> io::Result<Option<DirEntry>> {
+ match self.tokio.next_entry().await {
+ Ok(entry) => Ok(entry.map(|e| DirEntry { tokio: e })),
+ Err(err) => Err(Error::build(err, ErrorKind::ReadDir, &self.path)),
+ }
+ }
+
+ /// Wrapper around [`tokio::fs::ReadDir::poll_next_entry`].
+ pub fn poll_next_entry(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<Option<DirEntry>>> {
+ Poll::Ready(match ready!(self.tokio.poll_next_entry(cx)) {
+ Ok(entry) => Ok(entry.map(|e| DirEntry { tokio: e })),
+ Err(err) => Err(Error::build(err, ErrorKind::ReadDir, &self.path)),
+ })
+ }
+}
+
+/// Entries returned by the [`ReadDir`] stream.
+///
+/// This is a wrapper around [`tokio::fs::DirEntry`].
+#[derive(Debug)]
+#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
+pub struct DirEntry {
+ tokio: fs::DirEntry,
+}
+
+impl DirEntry {
+ /// Wrapper around [`tokio::fs::DirEntry::path`].
+ pub fn path(&self) -> PathBuf {
+ self.tokio.path()
+ }
+
+ /// Wrapper around [`tokio::fs::DirEntry::file_name`].
+ pub fn file_name(&self) -> OsString {
+ self.tokio.file_name()
+ }
+
+ /// Wrapper around [`tokio::fs::DirEntry::metadata`].
+ pub async fn metadata(&self) -> io::Result<Metadata> {
+ self.tokio
+ .metadata()
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::Metadata, self.path()))
+ }
+
+ /// Wrapper around [`tokio::fs::DirEntry::file_type`].
+ pub async fn file_type(&self) -> io::Result<FileType> {
+ self.tokio
+ .file_type()
+ .await
+ .map_err(|err| Error::build(err, ErrorKind::Metadata, self.path()))
+ }
+}
+
+#[cfg(unix)]
+impl DirEntry {
+ /// Wrapper around [`tokio::fs::DirEntry::ino`].
+ pub fn ino(&self) -> u64 {
+ self.tokio.ino()
+ }
+}
|