use std::fmt::Debug;
use std::future::ready;
use std::hash::Hash;
use std::hash::Hasher;
use std::mem;
use std::sync::Arc;
use futures::Future;
use crate::raw::*;
use crate::*;
pub trait Access: Send + Sync + Debug + Unpin + 'static {
type Reader: oio::Read;
type Writer: oio::Write;
type Lister: oio::List;
type Deleter: oio::Delete;
fn info(&self) -> Arc<AccessorInfo>;
fn create_dir(
&self,
path: &str,
args: OpCreateDir,
) -> impl Future<Output = Result<RpCreateDir>> + MaybeSend {
let (_, _) = (path, args);
ready(Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
)))
}
fn stat(&self, path: &str, args: OpStat) -> impl Future<Output = Result<RpStat>> + MaybeSend {
let (_, _) = (path, args);
ready(Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
)))
}
fn read(
&self,
path: &str,
args: OpRead,
) -> impl Future<Output = Result<(RpRead, Self::Reader)>> + MaybeSend {
let (_, _) = (path, args);
ready(Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
)))
}
fn write(
&self,
path: &str,
args: OpWrite,
) -> impl Future<Output = Result<(RpWrite, Self::Writer)>> + MaybeSend {
let (_, _) = (path, args);
ready(Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
)))
}
fn delete(&self) -> impl Future<Output = Result<(RpDelete, Self::Deleter)>> + MaybeSend {
ready(Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
)))
}
fn list(
&self,
path: &str,
args: OpList,
) -> impl Future<Output = Result<(RpList, Self::Lister)>> + MaybeSend {
let (_, _) = (path, args);
ready(Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
)))
}
fn copy(
&self,
from: &str,
to: &str,
args: OpCopy,
) -> impl Future<Output = Result<RpCopy>> + MaybeSend {
let (_, _, _) = (from, to, args);
ready(Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
)))
}
fn rename(
&self,
from: &str,
to: &str,
args: OpRename,
) -> impl Future<Output = Result<RpRename>> + MaybeSend {
let (_, _, _) = (from, to, args);
ready(Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
)))
}
fn presign(
&self,
path: &str,
args: OpPresign,
) -> impl Future<Output = Result<RpPresign>> + MaybeSend {
let (_, _) = (path, args);
ready(Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
)))
}
}
pub trait AccessDyn: Send + Sync + Debug + Unpin {
fn info_dyn(&self) -> Arc<AccessorInfo>;
fn create_dir_dyn<'a>(
&'a self,
path: &'a str,
args: OpCreateDir,
) -> BoxedFuture<'a, Result<RpCreateDir>>;
fn stat_dyn<'a>(&'a self, path: &'a str, args: OpStat) -> BoxedFuture<'a, Result<RpStat>>;
fn read_dyn<'a>(
&'a self,
path: &'a str,
args: OpRead,
) -> BoxedFuture<'a, Result<(RpRead, oio::Reader)>>;
fn write_dyn<'a>(
&'a self,
path: &'a str,
args: OpWrite,
) -> BoxedFuture<'a, Result<(RpWrite, oio::Writer)>>;
fn delete_dyn(&self) -> BoxedFuture<'_, Result<(RpDelete, oio::Deleter)>>;
fn list_dyn<'a>(
&'a self,
path: &'a str,
args: OpList,
) -> BoxedFuture<'a, Result<(RpList, oio::Lister)>>;
fn copy_dyn<'a>(
&'a self,
from: &'a str,
to: &'a str,
args: OpCopy,
) -> BoxedFuture<'a, Result<RpCopy>>;
fn rename_dyn<'a>(
&'a self,
from: &'a str,
to: &'a str,
args: OpRename,
) -> BoxedFuture<'a, Result<RpRename>>;
fn presign_dyn<'a>(
&'a self,
path: &'a str,
args: OpPresign,
) -> BoxedFuture<'a, Result<RpPresign>>;
}
impl<A: ?Sized> AccessDyn for A
where
A: Access<
Reader = oio::Reader,
Writer = oio::Writer,
Lister = oio::Lister,
Deleter = oio::Deleter,
>,
{
fn info_dyn(&self) -> Arc<AccessorInfo> {
self.info()
}
fn create_dir_dyn<'a>(
&'a self,
path: &'a str,
args: OpCreateDir,
) -> BoxedFuture<'a, Result<RpCreateDir>> {
Box::pin(self.create_dir(path, args))
}
fn stat_dyn<'a>(&'a self, path: &'a str, args: OpStat) -> BoxedFuture<'a, Result<RpStat>> {
Box::pin(self.stat(path, args))
}
fn read_dyn<'a>(
&'a self,
path: &'a str,
args: OpRead,
) -> BoxedFuture<'a, Result<(RpRead, oio::Reader)>> {
Box::pin(self.read(path, args))
}
fn write_dyn<'a>(
&'a self,
path: &'a str,
args: OpWrite,
) -> BoxedFuture<'a, Result<(RpWrite, oio::Writer)>> {
Box::pin(self.write(path, args))
}
fn delete_dyn(&self) -> BoxedFuture<'_, Result<(RpDelete, oio::Deleter)>> {
Box::pin(self.delete())
}
fn list_dyn<'a>(
&'a self,
path: &'a str,
args: OpList,
) -> BoxedFuture<'a, Result<(RpList, oio::Lister)>> {
Box::pin(self.list(path, args))
}
fn copy_dyn<'a>(
&'a self,
from: &'a str,
to: &'a str,
args: OpCopy,
) -> BoxedFuture<'a, Result<RpCopy>> {
Box::pin(self.copy(from, to, args))
}
fn rename_dyn<'a>(
&'a self,
from: &'a str,
to: &'a str,
args: OpRename,
) -> BoxedFuture<'a, Result<RpRename>> {
Box::pin(self.rename(from, to, args))
}
fn presign_dyn<'a>(
&'a self,
path: &'a str,
args: OpPresign,
) -> BoxedFuture<'a, Result<RpPresign>> {
Box::pin(self.presign(path, args))
}
}
impl Access for dyn AccessDyn {
type Reader = oio::Reader;
type Writer = oio::Writer;
type Deleter = oio::Deleter;
type Lister = oio::Lister;
fn info(&self) -> Arc<AccessorInfo> {
self.info_dyn()
}
async fn create_dir(&self, path: &str, args: OpCreateDir) -> Result<RpCreateDir> {
self.create_dir_dyn(path, args).await
}
async fn stat(&self, path: &str, args: OpStat) -> Result<RpStat> {
self.stat_dyn(path, args).await
}
async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> {
self.read_dyn(path, args).await
}
async fn write(&self, path: &str, args: OpWrite) -> Result<(RpWrite, Self::Writer)> {
self.write_dyn(path, args).await
}
async fn delete(&self) -> Result<(RpDelete, Self::Deleter)> {
self.delete_dyn().await
}
async fn list(&self, path: &str, args: OpList) -> Result<(RpList, Self::Lister)> {
self.list_dyn(path, args).await
}
async fn copy(&self, from: &str, to: &str, args: OpCopy) -> Result<RpCopy> {
self.copy_dyn(from, to, args).await
}
async fn rename(&self, from: &str, to: &str, args: OpRename) -> Result<RpRename> {
self.rename_dyn(from, to, args).await
}
async fn presign(&self, path: &str, args: OpPresign) -> Result<RpPresign> {
self.presign_dyn(path, args).await
}
}
impl Access for () {
type Reader = ();
type Writer = ();
type Lister = ();
type Deleter = ();
fn info(&self) -> Arc<AccessorInfo> {
let ai = AccessorInfo::default();
ai.set_scheme("dummy")
.set_root("")
.set_name("dummy")
.set_native_capability(Capability::default());
ai.into()
}
}
#[allow(clippy::manual_async_fn)]
impl<T: Access + ?Sized> Access for Arc<T> {
type Reader = T::Reader;
type Writer = T::Writer;
type Lister = T::Lister;
type Deleter = T::Deleter;
fn info(&self) -> Arc<AccessorInfo> {
self.as_ref().info()
}
fn create_dir(
&self,
path: &str,
args: OpCreateDir,
) -> impl Future<Output = Result<RpCreateDir>> + MaybeSend {
async move { self.as_ref().create_dir(path, args).await }
}
fn stat(&self, path: &str, args: OpStat) -> impl Future<Output = Result<RpStat>> + MaybeSend {
async move { self.as_ref().stat(path, args).await }
}
fn read(
&self,
path: &str,
args: OpRead,
) -> impl Future<Output = Result<(RpRead, Self::Reader)>> + MaybeSend {
async move { self.as_ref().read(path, args).await }
}
fn write(
&self,
path: &str,
args: OpWrite,
) -> impl Future<Output = Result<(RpWrite, Self::Writer)>> + MaybeSend {
async move { self.as_ref().write(path, args).await }
}
fn delete(&self) -> impl Future<Output = Result<(RpDelete, Self::Deleter)>> + MaybeSend {
async move { self.as_ref().delete().await }
}
fn list(
&self,
path: &str,
args: OpList,
) -> impl Future<Output = Result<(RpList, Self::Lister)>> + MaybeSend {
async move { self.as_ref().list(path, args).await }
}
fn copy(
&self,
from: &str,
to: &str,
args: OpCopy,
) -> impl Future<Output = Result<RpCopy>> + MaybeSend {
async move { self.as_ref().copy(from, to, args).await }
}
fn rename(
&self,
from: &str,
to: &str,
args: OpRename,
) -> impl Future<Output = Result<RpRename>> + MaybeSend {
async move { self.as_ref().rename(from, to, args).await }
}
fn presign(
&self,
path: &str,
args: OpPresign,
) -> impl Future<Output = Result<RpPresign>> + MaybeSend {
async move { self.as_ref().presign(path, args).await }
}
}
pub type Accessor = Arc<dyn AccessDyn>;
#[derive(Debug)]
struct AccessorInfoInner {
scheme: &'static str,
root: Arc<str>,
name: Arc<str>,
native_capability: Capability,
full_capability: Capability,
http_client: HttpClient,
executor: Executor,
}
impl Default for AccessorInfoInner {
fn default() -> Self {
Self {
scheme: "unknown",
root: Arc::from(""),
name: Arc::from(""),
native_capability: Capability::default(),
full_capability: Capability::default(),
http_client: HttpClient::default(),
executor: Executor::default(),
}
}
}
#[derive(Debug, Default)]
pub struct AccessorInfo {
inner: std::sync::RwLock<AccessorInfoInner>,
}
impl PartialEq for AccessorInfo {
fn eq(&self, other: &Self) -> bool {
self.scheme() == other.scheme()
&& self.root() == other.root()
&& self.name() == other.name()
}
}
impl Eq for AccessorInfo {}
impl Hash for AccessorInfo {
fn hash<H: Hasher>(&self, state: &mut H) {
self.scheme().hash(state);
self.root().hash(state);
self.name().hash(state);
}
}
impl AccessorInfo {
pub fn scheme(&self) -> &'static str {
match self.inner.read() {
Ok(v) => v.scheme,
Err(err) => err.get_ref().scheme,
}
}
pub fn set_scheme(&self, scheme: &'static str) -> &Self {
if let Ok(mut v) = self.inner.write() {
v.scheme = scheme;
}
self
}
pub fn root(&self) -> Arc<str> {
match self.inner.read() {
Ok(v) => v.root.clone(),
Err(err) => err.get_ref().root.clone(),
}
}
pub fn set_root(&self, root: &str) -> &Self {
if let Ok(mut v) = self.inner.write() {
v.root = Arc::from(root);
}
self
}
pub fn name(&self) -> Arc<str> {
match self.inner.read() {
Ok(v) => v.name.clone(),
Err(err) => err.get_ref().name.clone(),
}
}
pub fn set_name(&self, name: &str) -> &Self {
if let Ok(mut v) = self.inner.write() {
v.name = Arc::from(name)
}
self
}
pub fn native_capability(&self) -> Capability {
match self.inner.read() {
Ok(v) => v.native_capability,
Err(err) => err.get_ref().native_capability,
}
}
pub fn set_native_capability(&self, capability: Capability) -> &Self {
if let Ok(mut v) = self.inner.write() {
v.native_capability = capability;
v.full_capability = capability;
}
self
}
pub fn full_capability(&self) -> Capability {
match self.inner.read() {
Ok(v) => v.full_capability,
Err(err) => err.get_ref().full_capability,
}
}
pub fn update_full_capability(&self, f: impl FnOnce(Capability) -> Capability) -> &Self {
if let Ok(mut v) = self.inner.write() {
v.full_capability = f(v.full_capability);
}
self
}
pub fn http_client(&self) -> HttpClient {
match self.inner.read() {
Ok(v) => v.http_client.clone(),
Err(err) => err.get_ref().http_client.clone(),
}
}
pub fn update_http_client(&self, f: impl FnOnce(HttpClient) -> HttpClient) -> &Self {
if let Ok(mut v) = self.inner.write() {
let client = mem::take(&mut v.http_client);
v.http_client = f(client);
}
self
}
pub fn executor(&self) -> Executor {
match self.inner.read() {
Ok(v) => v.executor.clone(),
Err(err) => err.get_ref().executor.clone(),
}
}
pub fn update_executor(&self, f: impl FnOnce(Executor) -> Executor) -> &Self {
if let Ok(mut v) = self.inner.write() {
let executor = mem::take(&mut v.executor);
v.executor = f(executor);
}
self
}
}