use openscript::{Value, Error, Result};
use tokio::fs;
use std::path::Path;
use tokio::io::AsyncWriteExt;
pub async fn read_file(path: &str) -> Result<String> {
match fs::read_to_string(path).await {
Ok(content) => Ok(content),
Err(e) => Err(Error::runtime_error(format!("Failed to read file '{}': {}", path, e))),
}
}
pub async fn write_file(path: &str, content: &str) -> Result<()> {
match fs::write(path, content).await {
Ok(()) => Ok(()),
Err(e) => Err(Error::runtime_error(format!("Failed to write file '{}': {}", path, e))),
}
}
pub async fn append_file(path: &str, content: &str) -> Result<()> {
match fs::OpenOptions::new().create(true).append(true).open(path).await {
Ok(mut file) => {
match file.write_all(content.as_bytes()).await {
Ok(()) => Ok(()),
Err(e) => Err(Error::runtime_error(format!("Failed to append to file '{}': {}", path, e))),
}
}
Err(e) => Err(Error::runtime_error(format!("Failed to open file '{}': {}", path, e))),
}
}
pub async fn exists(path: &str) -> Result<bool> {
Ok(Path::new(path).exists())
}
pub async fn is_file(path: &str) -> Result<bool> {
Ok(Path::new(path).is_file())
}
pub async fn is_dir(path: &str) -> Result<bool> {
Ok(Path::new(path).is_dir())
}
pub async fn mkdir(path: &str) -> Result<()> {
match fs::create_dir_all(path).await {
Ok(()) => Ok(()),
Err(e) => Err(Error::runtime_error(format!("Failed to create directory '{}': {}", path, e))),
}
}
pub async fn rmdir(path: &str) -> Result<()> {
match fs::remove_dir(path).await {
Ok(()) => Ok(()),
Err(e) => Err(Error::runtime_error(format!("Failed to remove directory '{}': {}", path, e))),
}
}
pub async fn remove(path: &str) -> Result<()> {
match fs::remove_file(path).await {
Ok(()) => Ok(()),
Err(e) => Err(Error::runtime_error(format!("Failed to remove file '{}': {}", path, e))),
}
}
pub async fn copy(from: &str, to: &str) -> Result<()> {
match fs::copy(from, to).await {
Ok(_) => Ok(()),
Err(e) => Err(Error::runtime_error(format!("Failed to copy '{}' to '{}': {}", from, to, e))),
}
}
pub async fn rename(from: &str, to: &str) -> Result<()> {
match fs::rename(from, to).await {
Ok(()) => Ok(()),
Err(e) => Err(Error::runtime_error(format!("Failed to move '{}' to '{}': {}", from, to, e))),
}
}
pub async fn list_dir(path: &str) -> Result<Vec<Value>> {
match fs::read_dir(path).await {
Ok(mut entries) => {
let mut items = Vec::new();
while let Ok(Some(entry)) = entries.next_entry().await {
if let Some(name) = entry.file_name().to_str() {
items.push(Value::String(name.to_string()));
}
}
Ok(items)
}
Err(e) => Err(Error::runtime_error(format!("Failed to list directory '{}': {}", path, e))),
}
}
pub async fn file_size(path: &str) -> Result<u64> {
match fs::metadata(path).await {
Ok(metadata) => Ok(metadata.len()),
Err(e) => Err(Error::runtime_error(format!("Failed to get file size for '{}': {}", path, e))),
}
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::TempDir;
#[tokio::test]
async fn test_file_operations() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.txt");
let file_path_str = file_path.to_str().unwrap();
write_file(file_path_str, "Hello, World!").await.unwrap();
let result = read_file(file_path_str).await.unwrap();
assert_eq!(result, "Hello, World!");
let result = exists(file_path_str).await.unwrap();
assert_eq!(result, true);
let result = is_file(file_path_str).await.unwrap();
assert_eq!(result, true);
let result = file_size(file_path_str).await.unwrap();
assert_eq!(result, 13); }
}