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
extern crate glob; extern crate nc; use nc::mode_t; use nc::Errno; use std::path::Path; use crate::expand_env; pub struct MkDirOptions { pub recursive: bool, pub mode: mode_t, pub exist_ok: bool, pub expand_env: bool, } impl MkDirOptions { pub fn new() -> MkDirOptions { Self::default() } } impl Default for MkDirOptions { fn default() -> MkDirOptions { MkDirOptions { recursive: false, mode: 0o755, exist_ok: false, expand_env: true, } } } pub fn mkdir<T: AsRef<str>>(directory: T, options: &MkDirOptions) -> Result<(), Errno> { let exist_ok = if options.recursive { true } else { options.recursive }; let directory = if options.expand_env { expand_env(directory) } else { directory.as_ref().to_string() }; let path = Path::new(&directory); do_mkdir(path, options.recursive, options.mode, exist_ok) } fn do_mkdir(p: &Path, recursive: bool, mode: mode_t, exist_ok: bool) -> Result<(), Errno> { if p.exists() { if exist_ok { return Ok(()); } else { return Err(nc::EEXIST); } } if recursive { match p.parent() { Some(parent) => do_mkdir(parent, recursive, mode, true)?, None => return Err(nc::ENOENT), } } let p = p.to_str().unwrap(); nc::mkdir(p, mode) } #[cfg(test)] mod tests { use super::{mkdir, MkDirOptions}; #[test] fn test_mkdir() { let mut options = MkDirOptions::new(); options.recursive = true; let ret = mkdir("/tmp/test1/test2", &options); assert_eq!(ret, Ok(())); } }