You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
1.9 KiB

3 years ago
use crate::{UError, UResult};
use std::{env::temp_dir, fs, ops::Drop, os::unix::fs::PermissionsExt, path::PathBuf};
use uuid::Uuid;
pub struct TempFile {
path: PathBuf,
}
impl TempFile {
pub fn get_path(&self) -> String {
self.path.to_string_lossy().to_string()
}
pub fn new() -> Self {
let name = Uuid::simple(&Uuid::new_v4()).to_string();
let mut path = temp_dir();
path.push(name);
Self { path }
}
3 years ago
pub fn write_all(&self, data: &[u8]) -> UResult<()> {
fs::write(&self.path, data).map_err(|e| UError::FSError(self.get_path(), e.to_string()))?;
Ok(())
}
3 years ago
pub fn write_exec(data: &[u8]) -> UResult<Self> {
let this = Self::new();
let path = this.get_path();
dbg!(&path);
3 years ago
this.write_all(data)?;
let perms = fs::Permissions::from_mode(0o555);
3 years ago
fs::set_permissions(&path, perms).map_err(|e| UError::FSError(path, e.to_string()))?;
Ok(this)
}
}
impl Drop for TempFile {
fn drop(&mut self) {
fs::remove_file(&self.path).unwrap();
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::utils::bytes_to_string;
use std::path::Path;
use std::process::Command;
#[test]
fn test_file_is_not_busy() {
let binary = include_bytes!("../../tests/fixtures/echoer");
for _ in 0..100 {
let executable = TempFile::write_exec(binary).unwrap();
let path = executable.get_path();
let result = Command::new(path).arg("qwe").output().unwrap();
assert_eq!(bytes_to_string(result.stdout.as_ref()).trim(), "qwe");
}
}
#[test]
fn test_file_removed_after_dropping() {
let path;
{
let file = TempFile::new();
file.write_all(b"asdqwe").unwrap();
path = file.get_path();
assert!(Path::new(&path).exists())
}
assert!(!Path::new(&path).exists())
}
}