1 use crate::errors::{Error, ErrorKind};
2 use std::ffi::OsString;
3 use std::fs::{FileType, Metadata};
4 use std::io;
5 use std::path::{Path, PathBuf};
6 use std::task::{ready, Context, Poll};
7 use tokio::fs;
8 
9 /// Returns a stream over the entries within a directory.
10 ///
11 /// Wrapper for [`tokio::fs::read_dir`].
12 #[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
read_dir(path: impl AsRef<Path>) -> io::Result<ReadDir>13 pub async fn read_dir(path: impl AsRef<Path>) -> io::Result<ReadDir> {
14     let path = path.as_ref();
15     let tokio = fs::read_dir(path)
16         .await
17         .map_err(|err| Error::build(err, ErrorKind::ReadDir, path))?;
18     Ok(ReadDir {
19         tokio,
20         path: path.to_owned(),
21     })
22 }
23 
24 /// Reads the entries in a directory.
25 ///
26 /// This is a wrapper around [`tokio::fs::ReadDir`].
27 #[derive(Debug)]
28 #[must_use = "streams do nothing unless polled"]
29 #[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
30 pub struct ReadDir {
31     tokio: fs::ReadDir,
32     path: PathBuf,
33 }
34 
35 impl ReadDir {
36     /// Returns the next entry in the directory stream.
37     ///
38     /// Wrapper around [`tokio::fs::ReadDir::next_entry`].
next_entry(&mut self) -> io::Result<Option<DirEntry>>39     pub async fn next_entry(&mut self) -> io::Result<Option<DirEntry>> {
40         match self.tokio.next_entry().await {
41             Ok(entry) => Ok(entry.map(|e| DirEntry { tokio: e })),
42             Err(err) => Err(Error::build(err, ErrorKind::ReadDir, &self.path)),
43         }
44     }
45 
46     /// Polls for the next directory entry in the stream.
47     ///
48     /// Wrapper around [`tokio::fs::ReadDir::poll_next_entry`].
poll_next_entry(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<Option<DirEntry>>>49     pub fn poll_next_entry(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<Option<DirEntry>>> {
50         Poll::Ready(match ready!(self.tokio.poll_next_entry(cx)) {
51             Ok(entry) => Ok(entry.map(|e| DirEntry { tokio: e })),
52             Err(err) => Err(Error::build(err, ErrorKind::ReadDir, &self.path)),
53         })
54     }
55 }
56 
57 /// Entries returned by the [`ReadDir`] stream.
58 ///
59 /// This is a wrapper around [`tokio::fs::DirEntry`].
60 #[derive(Debug)]
61 #[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
62 pub struct DirEntry {
63     tokio: fs::DirEntry,
64 }
65 
66 impl DirEntry {
67     /// Returns the full path to the file that this entry represents.
68     ///
69     /// Wrapper around [`tokio::fs::DirEntry::path`].
path(&self) -> PathBuf70     pub fn path(&self) -> PathBuf {
71         self.tokio.path()
72     }
73 
74     /// Returns the bare file name of this directory entry without any other
75     /// leading path component.
76     ///
77     /// Wrapper around [`tokio::fs::DirEntry::file_name`].
file_name(&self) -> OsString78     pub fn file_name(&self) -> OsString {
79         self.tokio.file_name()
80     }
81 
82     /// Returns the metadata for the file that this entry points at.
83     ///
84     /// Wrapper around [`tokio::fs::DirEntry::metadata`].
metadata(&self) -> io::Result<Metadata>85     pub async fn metadata(&self) -> io::Result<Metadata> {
86         self.tokio
87             .metadata()
88             .await
89             .map_err(|err| Error::build(err, ErrorKind::Metadata, self.path()))
90     }
91 
92     /// Returns the file type for the file that this entry points at.
93     ///
94     /// Wrapper around [`tokio::fs::DirEntry::file_type`].
file_type(&self) -> io::Result<FileType>95     pub async fn file_type(&self) -> io::Result<FileType> {
96         self.tokio
97             .file_type()
98             .await
99             .map_err(|err| Error::build(err, ErrorKind::Metadata, self.path()))
100     }
101 }
102 
103 #[cfg(unix)]
104 impl DirEntry {
105     /// Returns the underlying `d_ino` field in the contained `dirent` structure.
106     ///
107     /// Wrapper around [`tokio::fs::DirEntry::ino`].
ino(&self) -> u64108     pub fn ino(&self) -> u64 {
109         self.tokio.ino()
110     }
111 }
112