use std::fs;
use std::io;
use std::path::Path;
use super::AsyncFileIO;
#[derive(Debug, Clone, Copy, Default)]
pub struct BlockingIO;
impl BlockingIO {
pub fn new() -> Self {
Self
}
}
impl AsyncFileIO for BlockingIO {
fn read_sync(&self, path: &Path) -> io::Result<Vec<u8>> {
fs::read(path)
}
fn write_sync(&self, path: &Path, data: &[u8]) -> io::Result<()> {
if let Some(parent) = path.parent() {
if !parent.as_os_str().is_empty() && !parent.exists() {
fs::create_dir_all(parent)?;
}
}
fs::write(path, data)
}
fn read_batch_sync(&self, paths: &[&Path]) -> io::Result<Vec<io::Result<Vec<u8>>>> {
Ok(paths.iter().copied().map(fs::read).collect())
}
fn write_batch_sync(&self, files: &[(&Path, &[u8])]) -> io::Result<Vec<io::Result<()>>> {
Ok(files
.iter()
.map(|(path, data)| {
if let Some(parent) = path.parent() {
if !parent.as_os_str().is_empty() && !parent.exists() {
fs::create_dir_all(parent)?;
}
}
fs::write(path, data)
})
.collect())
}
fn backend_name(&self) -> &'static str {
"blocking"
}
fn is_available(&self) -> bool {
true }
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use tempfile::TempDir;
#[test]
fn test_blocking_read_write() {
let dir = TempDir::new().unwrap();
let path = dir.path().join("test.txt");
let io = BlockingIO::new();
let data = b"Hello, World!";
io.write_sync(&path, data).unwrap();
let read_data = io.read_sync(&path).unwrap();
assert_eq!(read_data, data);
}
#[test]
fn test_blocking_batch_operations() {
let dir = TempDir::new().unwrap();
let io = BlockingIO::new();
let files: Vec<_> = (0..3)
.map(|i| {
let path = dir.path().join(format!("file{}.txt", i));
let data = format!("Content {}", i);
(path, data)
})
.collect();
let write_refs: Vec<_> = files
.iter()
.map(|(p, d)| (p.as_path(), d.as_bytes()))
.collect();
let write_results = io.write_batch_sync(&write_refs).unwrap();
assert!(write_results.iter().all(|r| r.is_ok()));
let paths: Vec<_> = files.iter().map(|(p, _)| p.as_path()).collect();
let read_results = io.read_batch_sync(&paths).unwrap();
for (i, result) in read_results.iter().enumerate() {
let data = result.as_ref().unwrap();
assert_eq!(String::from_utf8_lossy(data), format!("Content {}", i));
}
}
#[test]
fn test_blocking_creates_parent_dirs() {
let dir = TempDir::new().unwrap();
let path = dir.path().join("nested").join("dir").join("test.txt");
let io = BlockingIO::new();
io.write_sync(&path, b"test").unwrap();
assert!(path.exists());
}
#[test]
fn test_blocking_backend_name() {
let io = BlockingIO::new();
assert_eq!(io.backend_name(), "blocking");
assert!(io.is_available());
}
}