crate::ix!();
pub async fn write_to_file(
target_path: impl AsRef<Path>,
serialized_json: &str
) -> Result<(), io::Error>
{
info!("writing some json content to file: {:?}", target_path.as_ref());
let mut target_file = File::create(&target_path).await?;
target_file.write_all(serialized_json.as_bytes()).await?;
target_file.flush().await?;
Ok(())
}
#[cfg(test)]
mod write_to_file_tests {
use super::*;
fn named_temp_file_with_path(prefix: &str) -> (PathBuf, NamedTempFile) {
let file = NamedTempFile::new().expect("Failed to create NamedTempFile");
let path = file.path().to_path_buf();
(path, file)
}
#[traced_test]
async fn test_write_to_file_success() {
info!("Starting test_write_to_file_success");
let (temp_path, _tempfile) = named_temp_file_with_path("success");
let json_content = r#"{"key": "value"}"#;
let result = write_to_file(&temp_path, json_content).await;
assert!(result.is_ok());
let written = fs::read_to_string(&temp_path).await.unwrap();
pretty_assert_eq!(written, json_content);
info!("test_write_to_file_success passed.");
}
#[traced_test]
async fn test_write_to_file_invalid_path() {
info!("Starting test_write_to_file_invalid_path");
let invalid_path = PathBuf::from("/invalid_path/test_output.json");
let json_content = r#"{"key": "value"}"#;
let result = write_to_file(&invalid_path, json_content).await;
assert!(result.is_err(), "Should fail writing to an invalid path");
info!("test_write_to_file_invalid_path passed.");
}
#[traced_test]
async fn returns_error_on_invalid_path() {
info!("Starting returns_error_on_invalid_path");
let invalid_path = PathBuf::from("/this/path/does/not/exist.json");
let json_content = r#"{"key": "value"}"#;
let result = write_to_file(&invalid_path, json_content).await;
debug!("Result from write_to_file: {:?}", result);
assert!(result.is_err(), "Expected an I/O error for invalid path");
info!("returns_error_on_invalid_path passed.");
}
#[traced_test]
async fn overwrites_existing_file() {
info!("Starting overwrites_existing_file");
let (temp_path, _tempfile) = named_temp_file_with_path("overwrite");
let initial = r#"{"initial": "data"}"#;
let updated = r#"{"updated": "data"}"#;
write_to_file(&temp_path, initial).await.unwrap();
write_to_file(&temp_path, updated).await.unwrap();
let final_contents = fs::read_to_string(&temp_path).await.unwrap();
pretty_assert_eq!(final_contents, updated);
info!("overwrites_existing_file passed.");
}
#[traced_test]
async fn handles_empty_content() {
info!("Starting handles_empty_content");
let (temp_path, _tempfile) = named_temp_file_with_path("empty");
let empty_content = "";
write_to_file(&temp_path, empty_content).await.unwrap();
let read_back = fs::read_to_string(&temp_path).await.unwrap();
assert!(read_back.is_empty(), "File should be empty after writing empty string");
info!("handles_empty_content passed.");
}
#[traced_test]
async fn handles_concurrent_writes() {
info!("Starting handles_concurrent_writes");
let sets = vec![
("concurrent_test_1", r#"{"data": 1}"#),
("concurrent_test_2", r#"{"data": 2}"#),
("concurrent_test_3", r#"{"data": 3}"#),
];
let mut tasks = Vec::new();
let mut file_paths = Vec::new();
for (prefix, content) in sets {
let (path, tempfile) = named_temp_file_with_path(prefix);
let content = content.to_string();
file_paths.push((path.clone(), tempfile)); tasks.push(tokio::spawn(async move {
write_to_file(&path, &content).await
}));
}
for task in tasks {
let res = task.await.expect("Task panicked");
assert!(res.is_ok(), "Concurrent write task failed");
}
for (path, _tempfile) in file_paths {
let data = fs::read_to_string(&path).await.unwrap();
debug!("Read from {:?}: {}", path, data);
assert!(data.contains("data"), "Content mismatch in concurrency test");
}
info!("handles_concurrent_writes passed.");
}
#[traced_test]
async fn writes_json_content_correctly() {
trace!("===== BEGIN_TEST: writes_json_content_correctly =====");
let (temp_path, _tempfile) = named_temp_file_with_path("writes_json_content_correctly");
let json_content = r#"{"key": "value"}"#;
let result = write_to_file(&temp_path, json_content).await;
debug!("write_to_file result: {:?}", result);
assert!(result.is_ok(), "Expected Ok from write_to_file");
let read_content = fs::read_to_string(&temp_path)
.await
.expect("Failed to read test file");
pretty_assert_eq!(read_content, json_content);
trace!("===== END_TEST: writes_json_content_correctly =====");
}
}