async_std/fs/
dir_builder.rs

1use std::future::Future;
2
3use crate::io;
4use crate::path::Path;
5use crate::task::spawn_blocking;
6
7/// A builder for creating directories with configurable options.
8///
9/// For Unix-specific options, import the [`os::unix::fs::DirBuilderExt`] trait.
10///
11/// This type is an async version of [`std::fs::DirBuilder`].
12///
13/// [`os::unix::fs::DirBuilderExt`]: ../os/unix/fs/trait.DirBuilderExt.html
14/// [`std::fs::DirBuilder`]: https://doc.rust-lang.org/std/fs/struct.DirBuilder.html
15#[derive(Debug, Default)]
16pub struct DirBuilder {
17    /// Set to `true` if non-existent parent directories should be created.
18    recursive: bool,
19
20    /// Unix mode for newly created directories.
21    #[cfg(unix)]
22    mode: Option<u32>,
23}
24
25impl DirBuilder {
26    /// Creates a blank set of options.
27    ///
28    /// The [`recursive`] option is initially set to `false`.
29    ///
30    /// [`recursive`]: #method.recursive
31    ///
32    /// # Examples
33    ///
34    /// ```
35    /// use async_std::fs::DirBuilder;
36    ///
37    /// let builder = DirBuilder::new();
38    /// ```
39    pub fn new() -> DirBuilder {
40        #[cfg(not(unix))]
41        let builder = DirBuilder { recursive: false };
42
43        #[cfg(unix)]
44        let builder = DirBuilder {
45            recursive: false,
46            mode: None,
47        };
48
49        builder
50    }
51
52    /// Sets the option for recursive mode.
53    ///
54    /// When set to `true`, this option means all parent directories should be created recursively
55    /// if they don't exist. Parents are created with the same permissions as the final directory.
56    ///
57    /// This option is initially set to `false`.
58    ///
59    /// # Examples
60    ///
61    /// ```
62    /// use async_std::fs::DirBuilder;
63    ///
64    /// let mut builder = DirBuilder::new();
65    /// builder.recursive(true);
66    /// ```
67    pub fn recursive(&mut self, recursive: bool) -> &mut Self {
68        self.recursive = recursive;
69        self
70    }
71
72    /// Creates a directory with the configured options.
73    ///
74    /// It is considered an error if the directory already exists unless recursive mode is enabled.
75    ///
76    /// # Errors
77    ///
78    /// An error will be returned in the following situations:
79    ///
80    /// * `path` already points to an existing file or directory.
81    /// * The current process lacks permissions to create the directory or its missing parents.
82    /// * Some other I/O error occurred.
83    ///
84    /// # Examples
85    ///
86    /// ```no_run
87    /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
88    /// #
89    /// use async_std::fs::DirBuilder;
90    ///
91    /// DirBuilder::new()
92    ///     .recursive(true)
93    ///     .create("./some/directory")
94    ///     .await?;
95    /// #
96    /// # Ok(()) }) }
97    /// ```
98    pub fn create<P: AsRef<Path>>(&self, path: P) -> impl Future<Output = io::Result<()>> {
99        let mut builder = std::fs::DirBuilder::new();
100        builder.recursive(self.recursive);
101
102        #[cfg(unix)]
103        {
104            if let Some(mode) = self.mode {
105                std::os::unix::fs::DirBuilderExt::mode(&mut builder, mode);
106            }
107        }
108
109        let path = path.as_ref().to_owned();
110        async move { spawn_blocking(move || builder.create(path)).await }
111    }
112}
113
114cfg_unix! {
115    use crate::os::unix::fs::DirBuilderExt;
116
117    impl DirBuilderExt for DirBuilder {
118        fn mode(&mut self, mode: u32) -> &mut Self {
119            self.mode = Some(mode);
120            self
121        }
122    }
123}