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
use crate::fs::asyncify; use std::io; use std::path::Path; /// A builder for creating directories in various manners. /// /// Additional Unix-specific options are available via importing the /// [`DirBuilderExt`] trait. /// /// This is a specialized version of [`std::fs::DirBuilder`] for usage on /// the Tokio runtime. /// /// [std::fs::DirBuilder]: std::fs::DirBuilder /// [`DirBuilderExt`]: crate::fs::os::unix::DirBuilderExt #[derive(Debug, Default)] pub struct DirBuilder { /// Indicates whether to create parent directories if they are missing. recursive: bool, /// Set the Unix mode for newly created directories. #[cfg(unix)] pub(super) mode: Option<u32>, } impl DirBuilder { /// Creates a new set of options with default mode/security settings for all /// platforms and also non-recursive. /// /// This is an async version of [`std::fs::DirBuilder::new`][std] /// /// [std]: std::fs::DirBuilder::new /// /// # Examples /// /// ```no_run /// use tokio::fs::DirBuilder; /// /// let builder = DirBuilder::new(); /// ``` pub fn new() -> Self { Default::default() } /// Indicates whether to create directories recursively (including all parent directories). /// Parents that do not exist are created with the same security and permissions settings. /// /// This option defaults to `false`. /// /// This is an async version of [`std::fs::DirBuilder::recursive`][std] /// /// [std]: std::fs::DirBuilder::recursive /// /// # Examples /// /// ```no_run /// use tokio::fs::DirBuilder; /// /// let mut builder = DirBuilder::new(); /// builder.recursive(true); /// ``` pub fn recursive(&mut self, recursive: bool) -> &mut Self { self.recursive = recursive; self } /// Creates the specified directory with the configured options. /// /// It is considered an error if the directory already exists unless /// recursive mode is enabled. /// /// This is an async version of [`std::fs::DirBuilder::create`][std] /// /// [std]: std::fs::DirBuilder::create /// /// # Errors /// /// An error will be returned under the following circumstances: /// /// * Path already points to an existing file. /// * Path already points to an existing directory and the mode is /// non-recursive. /// * The calling process doesn't have permissions to create the directory /// or its missing parents. /// * Other I/O error occurred. /// /// # Examples /// /// ```no_run /// use tokio::fs::DirBuilder; /// use std::io; /// /// #[tokio::main] /// async fn main() -> io::Result<()> { /// DirBuilder::new() /// .recursive(true) /// .create("/tmp/foo/bar/baz") /// .await?; /// /// Ok(()) /// } /// ``` pub async fn create<P: AsRef<Path>>(&self, path: P) -> io::Result<()> { let path = path.as_ref().to_owned(); 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); } } asyncify(move || builder.create(path)).await } }