async_std/fs/dir_entry.rs
1use std::ffi::OsString;
2use std::fmt;
3use std::sync::Arc;
4
5use crate::fs::{FileType, Metadata};
6use crate::io;
7use crate::path::PathBuf;
8use crate::task::spawn_blocking;
9
10/// An entry in a directory.
11///
12/// A stream of entries in a directory is returned by [`read_dir`].
13///
14/// This type is an async version of [`std::fs::DirEntry`].
15///
16/// [`read_dir`]: fn.read_dir.html
17/// [`std::fs::DirEntry`]: https://doc.rust-lang.org/std/fs/struct.DirEntry.html
18pub struct DirEntry(Arc<std::fs::DirEntry>);
19
20impl DirEntry {
21 /// Creates an asynchronous `DirEntry` from a synchronous one.
22 pub(crate) fn new(inner: std::fs::DirEntry) -> DirEntry {
23 DirEntry(Arc::new(inner))
24 }
25
26 /// Returns the full path to this entry.
27 ///
28 /// The full path is created by joining the original path passed to [`read_dir`] with the name
29 /// of this entry.
30 ///
31 /// [`read_dir`]: fn.read_dir.html
32 ///
33 /// # Examples
34 ///
35 /// ```no_run
36 /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
37 /// #
38 /// use async_std::fs;
39 /// use async_std::prelude::*;
40 ///
41 /// let mut dir = fs::read_dir(".").await?;
42 ///
43 /// while let Some(res) = dir.next().await {
44 /// let entry = res?;
45 /// println!("{:?}", entry.path());
46 /// }
47 /// #
48 /// # Ok(()) }) }
49 /// ```
50 pub fn path(&self) -> PathBuf {
51 self.0.path().into()
52 }
53
54 /// Reads the metadata for this entry.
55 ///
56 /// This function will traverse symbolic links to read the metadata.
57 ///
58 /// If you want to read metadata without following symbolic links, use [`symlink_metadata`]
59 /// instead.
60 ///
61 /// [`symlink_metadata`]: fn.symlink_metadata.html
62 ///
63 /// # Errors
64 ///
65 /// An error will be returned in the following situations:
66 ///
67 /// * This entry does not point to an existing file or directory anymore.
68 /// * The current process lacks permissions to read the metadata.
69 /// * Some other I/O error occurred.
70 ///
71 /// # Examples
72 ///
73 /// ```no_run
74 /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
75 /// #
76 /// use async_std::fs;
77 /// use async_std::prelude::*;
78 ///
79 /// let mut dir = fs::read_dir(".").await?;
80 ///
81 /// while let Some(res) = dir.next().await {
82 /// let entry = res?;
83 /// println!("{:?}", entry.metadata().await?);
84 /// }
85 /// #
86 /// # Ok(()) }) }
87 /// ```
88 pub async fn metadata(&self) -> io::Result<Metadata> {
89 let inner = self.0.clone();
90 spawn_blocking(move || inner.metadata()).await
91 }
92
93 /// Reads the file type for this entry.
94 ///
95 /// This function will not traverse symbolic links if this entry points at one.
96 ///
97 /// If you want to read metadata with following symbolic links, use [`metadata`] instead.
98 ///
99 /// [`metadata`]: #method.metadata
100 ///
101 /// # Errors
102 ///
103 /// An error will be returned in the following situations:
104 ///
105 /// * This entry does not point to an existing file or directory anymore.
106 /// * The current process lacks permissions to read this entry's metadata.
107 /// * Some other I/O error occurred.
108 ///
109 /// # Examples
110 ///
111 /// ```no_run
112 /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
113 /// #
114 /// use async_std::fs;
115 /// use async_std::prelude::*;
116 ///
117 /// let mut dir = fs::read_dir(".").await?;
118 ///
119 /// while let Some(res) = dir.next().await {
120 /// let entry = res?;
121 /// println!("{:?}", entry.file_type().await?);
122 /// }
123 /// #
124 /// # Ok(()) }) }
125 /// ```
126 pub async fn file_type(&self) -> io::Result<FileType> {
127 let inner = self.0.clone();
128 spawn_blocking(move || inner.file_type()).await
129 }
130
131 /// Returns the bare name of this entry without the leading path.
132 ///
133 /// # Examples
134 ///
135 /// ```no_run
136 /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
137 /// #
138 /// use async_std::fs;
139 /// use async_std::prelude::*;
140 ///
141 /// let mut dir = fs::read_dir(".").await?;
142 ///
143 /// while let Some(res) = dir.next().await {
144 /// let entry = res?;
145 /// println!("{}", entry.file_name().to_string_lossy());
146 /// }
147 /// #
148 /// # Ok(()) }) }
149 /// ```
150 pub fn file_name(&self) -> OsString {
151 self.0.file_name()
152 }
153}
154
155impl fmt::Debug for DirEntry {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 f.debug_tuple("DirEntry").field(&self.path()).finish()
158 }
159}
160
161impl Clone for DirEntry {
162 fn clone(&self) -> Self {
163 DirEntry(self.0.clone())
164 }
165}
166
167cfg_unix! {
168 use crate::os::unix::fs::DirEntryExt;
169
170 impl DirEntryExt for DirEntry {
171 fn ino(&self) -> u64 {
172 self.0.ino()
173 }
174 }
175}