use std; use std::fs::{create_dir, File}; use std::io::ErrorKind; use std::io::Write; use std::path::{Path, PathBuf}; use rand; use rand::Rng; pub fn write_file_sync(path: &Path, content: &[u8]) -> std::io::Result<()> { let mut f = File::create(path)?; f.write_all(content) } pub fn make_temp_dir( dir: Option<&Path>, prefix: Option<&str>, suffix: Option<&str>, ) -> std::io::Result { let prefix_ = prefix.unwrap_or(""); let suffix_ = suffix.unwrap_or(""); let mut buf: PathBuf = match dir { Some(ref p) => p.to_path_buf(), None => std::env::temp_dir(), }.join("_"); let mut rng = rand::thread_rng(); loop { let unique = rng.gen::(); buf.set_file_name(format!("{}{:08x}{}", prefix_, unique, suffix_)); // TODO: on posix, set mode flags to 0o700. let r = create_dir(buf.as_path()); match r { Err(ref e) if e.kind() == ErrorKind::AlreadyExists => continue, Ok(_) => return Ok(buf), Err(e) => return Err(e), } } } pub fn mkdir(path: &Path) -> std::io::Result<()> { debug!("mkdir -p {}", path.display()); assert!(path.has_root(), "non-has_root not yet implemented"); std::fs::create_dir_all(path).or_else(|err| { if err.kind() == std::io::ErrorKind::AlreadyExists { Ok(()) } else { Err(err) } }) } pub fn normalize_path(path: &Path) -> String { let s = String::from(path.to_str().unwrap()); if cfg!(windows) { // TODO This isn't correct. Probbly should iterate over components. s.replace("\\", "/") } else { s } }