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 exist_ok: bool,
pub expand_env: bool,
pub mode: mode_t,
pub recursive: 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 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, options.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 options = MkDirOptions {
recursive: true,
exist_ok: true,
..Default::default()
};
let ret = mkdir("/tmp/test1/test2", &options);
assert_eq!(ret, Ok(()));
}
}