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