use std::fs::{File, OpenOptions};
use std::os::fd::{IntoRawFd, RawFd};
pub fn open_file_or_quiet(filename: Option<&str>) -> std::io::Result<RawFd> {
let file = filename.map_or_else(
|| File::open("/dev/null"),
|f| OpenOptions::new().append(true).create(true).open(f),
)?;
Ok(file.into_raw_fd())
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use std::io::Write;
use std::os::fd::FromRawFd;
use tempfile::tempdir;
#[cfg_attr(miri, ignore)] #[test]
fn test_open_file_or_quiet_none() {
let result = open_file_or_quiet(None);
assert!(result.is_ok());
let fd = result.unwrap();
assert!(fd >= 0);
let mut file = unsafe { File::from_raw_fd(fd) };
let write_result = writeln!(file, "should not fail");
if let Err(e) = write_result {
eprintln!(
"Writing to /dev/null failed with error kind: {:?}",
e.kind()
);
}
}
#[test]
fn test_open_file_or_quiet_new_file() {
let temp_dir = tempdir().unwrap();
let file_path = temp_dir.path().join("test_file.txt");
let file_path_str = file_path.to_str().unwrap();
let result = open_file_or_quiet(Some(file_path_str));
assert!(result.is_ok());
let fd = result.unwrap();
assert!(fd >= 0);
let mut file = unsafe { File::from_raw_fd(fd) };
writeln!(file, "hello world").unwrap();
drop(file);
assert!(file_path.exists());
let content = fs::read_to_string(&file_path).unwrap();
assert!(content.contains("hello world"));
}
#[test]
fn test_open_file_or_quiet_existing_file() {
let temp_dir = tempdir().unwrap();
let file_path = temp_dir.path().join("existing_file.txt");
let file_path_str = file_path.to_str().unwrap();
let mut file = File::create(&file_path).unwrap();
writeln!(file, "initial content").unwrap();
drop(file);
let result = open_file_or_quiet(Some(file_path_str));
assert!(result.is_ok());
let fd = result.unwrap();
assert!(fd >= 0);
let mut file = unsafe { File::from_raw_fd(fd) };
writeln!(file, "more content").unwrap();
drop(file);
assert!(file_path.exists());
let content = fs::read_to_string(&file_path).unwrap();
assert!(content.contains("initial content"));
assert!(content.contains("more content"));
}
#[test]
fn test_open_file_or_quiet_append_mode() {
let temp_dir = tempdir().unwrap();
let file_path = temp_dir.path().join("append_test.txt");
let file_path_str = file_path.to_str().unwrap();
let mut file = File::create(&file_path).unwrap();
writeln!(file, "initial content").unwrap();
drop(file);
let result = open_file_or_quiet(Some(file_path_str));
assert!(result.is_ok());
let fd = result.unwrap();
assert!(fd >= 0);
let mut file = unsafe { File::from_raw_fd(fd) };
writeln!(file, "appended content").unwrap();
drop(file);
let content = fs::read_to_string(&file_path).unwrap();
assert!(content.contains("initial content"));
assert!(content.contains("appended content"));
}
#[test]
fn test_open_file_or_quiet_invalid_path() {
let result = open_file_or_quiet(Some("/nonexistent/directory/file.txt"));
assert!(result.is_err());
let error = result.unwrap_err();
assert_eq!(error.kind(), std::io::ErrorKind::NotFound);
}
#[test]
fn test_open_file_or_quiet_empty_string() {
let result = open_file_or_quiet(Some(""));
assert!(result.is_err());
let error = result.unwrap_err();
assert_eq!(error.kind(), std::io::ErrorKind::NotFound);
}
#[test]
fn test_open_file_or_quiet_permission_denied() {
let result = open_file_or_quiet(Some("/root/protected_file.txt"));
if let Err(error) = result {
assert!(matches!(
error.kind(),
std::io::ErrorKind::NotFound | std::io::ErrorKind::PermissionDenied
));
}
}
#[test]
fn test_open_file_or_quiet_multiple_calls() {
let temp_dir = tempdir().unwrap();
let file_path = temp_dir.path().join("multi_test.txt");
let file_path_str = file_path.to_str().unwrap();
let fd1 = open_file_or_quiet(Some(file_path_str)).unwrap();
let fd2 = open_file_or_quiet(Some(file_path_str)).unwrap();
let fd3 = open_file_or_quiet(None).unwrap();
assert!(fd1 >= 0);
assert!(fd2 >= 0);
assert!(fd3 >= 0);
assert!(fd1 != fd2); assert!(fd3 != fd1);
assert!(fd3 != fd2);
unsafe {
libc::close(fd1);
libc::close(fd2);
libc::close(fd3);
}
}
}