#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
use adapters::{Adapter, AdapterInit};
use contents::Contents;
use mime::Mime;
use std::{
io::{Error, ErrorKind, Result},
path::{Path, PathBuf},
time::SystemTime,
};
use trait_object_hackyness::AdapterObject;
pub mod adapters;
mod contents;
mod trait_object_hackyness;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Visibility {
Public,
Private,
}
enum Resource {
File,
Directory,
}
#[derive(Debug)]
pub struct Filesystem {
adapter: Box<dyn AdapterObject>,
}
impl Filesystem {
pub async fn new<T: AdapterInit>(config: T::Config) -> std::result::Result<Self, T::Error> {
Ok(Self {
adapter: Box::new(T::new(config).await?),
})
}
pub fn from_adapter<T: Adapter + 'static>(adapter: T) -> Self {
Self {
adapter: Box::new(adapter),
}
}
pub async fn file_exists(&self, path: &Path) -> Result<bool> {
self.adapter.file_exists(path).await
}
pub async fn directory_exists(&self, path: &Path) -> Result<bool> {
self.adapter.directory_exists(path).await
}
pub async fn has(&self, path: &Path) -> Result<bool> {
let (file_exists, directory_exists) = futures::future::join(
self.adapter.file_exists(path),
self.adapter.directory_exists(path),
)
.await;
Ok(file_exists? || directory_exists?)
}
pub async fn write(&mut self, path: &Path, contents: &[u8]) -> Result<()> {
self.adapter.write(path, contents).await
}
pub async fn read<R: TryFrom<Contents>>(&mut self, path: &Path) -> Result<R> {
self.adapter.read(path).await.and_then(|c| {
c.try_into()
.map_err(|_| Error::new(ErrorKind::InvalidData, "Could not decode contents."))
})
}
pub async fn delete(&mut self, path: &Path) -> Result<()> {
self.adapter.delete(path).await
}
pub async fn delete_directory(&mut self, path: &Path) -> Result<()> {
self.adapter.delete_directory(path).await
}
pub async fn create_directory(&mut self, path: &Path) -> Result<()> {
self.adapter.create_directory(path).await
}
pub async fn list_contents(&self, path: &Path, deep: bool) -> Result<Vec<PathBuf>> {
self.adapter.list_contents(path, deep).await
}
pub async fn r#move(&mut self, source: &Path, destination: &Path) -> Result<()> {
self.adapter.r#move(source, destination).await
}
pub async fn copy(&mut self, source: &Path, destination: &Path) -> Result<()> {
self.adapter.copy(source, destination).await
}
pub async fn last_modified(&self, path: &Path) -> Result<SystemTime> {
self.adapter.last_modified(path).await
}
pub async fn file_size(&self, path: &Path) -> Result<u64> {
self.adapter.file_size(path).await
}
pub async fn mime_type(&self, path: &Path) -> Result<Mime> {
self.adapter.mime_type(path).await
}
pub async fn set_visibility(&mut self, path: &Path, visibility: Visibility) -> Result<()> {
self.adapter.set_visibility(path, visibility).await
}
pub async fn visibility(&self, path: &Path) -> Result<Visibility> {
self.adapter.visibility(path).await
}
pub async fn checksum(&self, path: &Path) -> Result<String> {
self.adapter.checksum(path).await
}
}