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}