use std::path::Path;
use tokio::{
fs,
io::{AsyncRead, AsyncWriteExt},
};
use crate::Error;
pub type File = Box<dyn AsyncRead + Unpin + Send>;
pub async fn open(path: impl AsRef<Path>) -> Result<File, Error> {
Ok(fs::File::open(path)
.await
.map(|file| Box::new(file) as File)?)
}
pub async fn exists(path: impl AsRef<Path>) -> bool {
fs::metadata(path).await.is_ok()
}
pub async fn write(path: impl AsRef<Path>, bytes: &[u8]) -> Result<(), Error> {
let Some(parent) = path.as_ref().parent() else {
return Err(Error::MissingParentPath(path.as_ref().to_owned()));
};
fs::create_dir_all(&parent).await?;
let mut file = fs::File::create(&path).await?;
file.write_all(bytes).await?;
Ok(())
}
pub async fn read_to_string(path: impl AsRef<Path>) -> Result<String, std::io::Error> {
fs::read_to_string(path).await
}
pub async fn get_file_modified_ts(path: &Path) -> Result<chrono::DateTime<chrono::Utc>, Error> {
let modified = tokio::fs::metadata(path).await.map(|m| m.modified())??;
Ok(chrono::DateTime::<chrono::Utc>::from(modified))
}