use std::fmt::Debug;
use std::future::Future;
use std::sync::Arc;
use crate::raw::*;
use crate::*;
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct ServiceInfo {
scheme: &'static str,
root: Arc<str>,
name: Arc<str>,
}
impl Debug for ServiceInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ServiceInfo")
.field("scheme", &self.scheme())
.field("root", &self.root())
.field("name", &self.name())
.finish_non_exhaustive()
}
}
impl ServiceInfo {
pub fn new(scheme: &'static str, root: impl AsRef<str>, name: impl AsRef<str>) -> Self {
Self {
scheme,
root: Arc::from(root.as_ref()),
name: Arc::from(name.as_ref()),
}
}
pub fn with_scheme(scheme: &'static str) -> Self {
Self::new(scheme, "", "")
}
pub fn with_root(&self, root: impl AsRef<str>) -> Self {
Self {
scheme: self.scheme,
root: Arc::from(root.as_ref()),
name: self.name.clone(),
}
}
pub fn scheme(&self) -> &'static str {
self.scheme
}
pub fn root(&self) -> Arc<str> {
self.root.clone()
}
pub fn name(&self) -> Arc<str> {
self.name.clone()
}
}
pub trait Service: Send + Sync + Debug + Unpin + 'static {
type Reader: oio::Read;
type Writer: oio::Write;
type Lister: oio::List;
type Deleter: oio::Delete;
type Copier: oio::Copy;
fn info(&self) -> ServiceInfo;
fn capability(&self) -> Capability;
fn create_dir(
&self,
ctx: &OperationContext,
path: &str,
args: OpCreateDir,
) -> impl Future<Output = Result<RpCreateDir>> + MaybeSend;
fn stat(
&self,
ctx: &OperationContext,
path: &str,
args: OpStat,
) -> impl Future<Output = Result<RpStat>> + MaybeSend;
fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader>;
fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<Self::Writer>;
fn delete(&self, ctx: &OperationContext) -> Result<Self::Deleter>;
fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<Self::Lister>;
fn copy(
&self,
ctx: &OperationContext,
from: &str,
to: &str,
args: OpCopy,
opts: OpCopier,
) -> Result<Self::Copier>;
fn rename(
&self,
ctx: &OperationContext,
from: &str,
to: &str,
args: OpRename,
) -> impl Future<Output = Result<RpRename>> + MaybeSend;
fn presign(
&self,
ctx: &OperationContext,
path: &str,
args: OpPresign,
) -> impl Future<Output = Result<RpPresign>> + MaybeSend;
}
pub trait ServiceDyn: Send + Sync + Debug + Unpin + 'static {
fn info_dyn(&self) -> ServiceInfo;
fn capability_dyn(&self) -> Capability;
fn create_dir_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpCreateDir,
) -> BoxedFuture<'a, Result<RpCreateDir>>;
fn stat_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpStat,
) -> BoxedFuture<'a, Result<RpStat>>;
fn read_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpRead,
) -> Result<oio::Reader>;
fn write_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpWrite,
) -> Result<oio::Writer>;
fn delete_dyn<'a>(&'a self, ctx: &'a OperationContext) -> Result<oio::Deleter>;
fn list_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpList,
) -> Result<oio::Lister>;
fn copy_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
from: &'a str,
to: &'a str,
args: OpCopy,
opts: OpCopier,
) -> Result<oio::Copier>;
fn rename_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
from: &'a str,
to: &'a str,
args: OpRename,
) -> BoxedFuture<'a, Result<RpRename>>;
fn presign_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpPresign,
) -> BoxedFuture<'a, Result<RpPresign>>;
}
pub type Servicer = Arc<dyn ServiceDyn>;
impl<S: Service + ?Sized> ServiceDyn for S {
fn info_dyn(&self) -> ServiceInfo {
self.info()
}
fn capability_dyn(&self) -> Capability {
self.capability()
}
fn create_dir_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpCreateDir,
) -> BoxedFuture<'a, Result<RpCreateDir>> {
Box::pin(self.create_dir(ctx, path, args))
}
fn stat_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpStat,
) -> BoxedFuture<'a, Result<RpStat>> {
Box::pin(self.stat(ctx, path, args))
}
fn read_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpRead,
) -> Result<oio::Reader> {
Ok(Box::new(self.read(ctx, path, args)?) as oio::Reader)
}
fn write_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpWrite,
) -> Result<oio::Writer> {
Ok(Box::new(self.write(ctx, path, args)?) as oio::Writer)
}
fn delete_dyn<'a>(&'a self, ctx: &'a OperationContext) -> Result<oio::Deleter> {
Ok(Box::new(self.delete(ctx)?) as oio::Deleter)
}
fn list_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpList,
) -> Result<oio::Lister> {
Ok(Box::new(self.list(ctx, path, args)?) as oio::Lister)
}
fn copy_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
from: &'a str,
to: &'a str,
args: OpCopy,
opts: OpCopier,
) -> Result<oio::Copier> {
Ok(Box::new(self.copy(ctx, from, to, args, opts)?) as oio::Copier)
}
fn rename_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
from: &'a str,
to: &'a str,
args: OpRename,
) -> BoxedFuture<'a, Result<RpRename>> {
Box::pin(self.rename(ctx, from, to, args))
}
fn presign_dyn<'a>(
&'a self,
ctx: &'a OperationContext,
path: &'a str,
args: OpPresign,
) -> BoxedFuture<'a, Result<RpPresign>> {
Box::pin(self.presign(ctx, path, args))
}
}
impl<T: ServiceDyn + ?Sized> Service for Arc<T> {
type Reader = oio::Reader;
type Writer = oio::Writer;
type Lister = oio::Lister;
type Deleter = oio::Deleter;
type Copier = oio::Copier;
fn info(&self) -> ServiceInfo {
self.as_ref().info_dyn()
}
fn capability(&self) -> Capability {
self.as_ref().capability_dyn()
}
async fn create_dir(
&self,
ctx: &OperationContext,
path: &str,
args: OpCreateDir,
) -> Result<RpCreateDir> {
self.as_ref().create_dir_dyn(ctx, path, args).await
}
async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
self.as_ref().stat_dyn(ctx, path, args).await
}
fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<oio::Reader> {
self.as_ref().read_dyn(ctx, path, args)
}
fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<oio::Writer> {
self.as_ref().write_dyn(ctx, path, args)
}
fn delete(&self, ctx: &OperationContext) -> Result<oio::Deleter> {
self.as_ref().delete_dyn(ctx)
}
fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<oio::Lister> {
self.as_ref().list_dyn(ctx, path, args)
}
fn copy(
&self,
ctx: &OperationContext,
from: &str,
to: &str,
args: OpCopy,
opts: OpCopier,
) -> Result<oio::Copier> {
self.as_ref().copy_dyn(ctx, from, to, args, opts)
}
async fn rename(
&self,
ctx: &OperationContext,
from: &str,
to: &str,
args: OpRename,
) -> Result<RpRename> {
self.as_ref().rename_dyn(ctx, from, to, args).await
}
async fn presign(
&self,
ctx: &OperationContext,
path: &str,
args: OpPresign,
) -> Result<RpPresign> {
self.as_ref().presign_dyn(ctx, path, args).await
}
}
impl Service for () {
type Reader = ();
type Writer = ();
type Lister = ();
type Deleter = ();
type Copier = ();
fn info(&self) -> ServiceInfo {
ServiceInfo::with_scheme("dummy")
}
fn capability(&self) -> Capability {
Capability::default()
}
async fn create_dir(
&self,
_: &OperationContext,
_: &str,
_: OpCreateDir,
) -> Result<RpCreateDir> {
Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
))
}
async fn stat(&self, _: &OperationContext, _: &str, _: OpStat) -> Result<RpStat> {
Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
))
}
fn read(&self, _: &OperationContext, _: &str, _: OpRead) -> Result<Self::Reader> {
Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
))
}
fn write(&self, _: &OperationContext, _: &str, _: OpWrite) -> Result<Self::Writer> {
Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
))
}
fn delete(&self, _: &OperationContext) -> Result<Self::Deleter> {
Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
))
}
fn list(&self, _: &OperationContext, _: &str, _: OpList) -> Result<Self::Lister> {
Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
))
}
fn copy(
&self,
_: &OperationContext,
_: &str,
_: &str,
_: OpCopy,
_: OpCopier,
) -> Result<Self::Copier> {
Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
))
}
async fn rename(
&self,
_: &OperationContext,
_: &str,
_: &str,
_: OpRename,
) -> Result<RpRename> {
Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
))
}
async fn presign(&self, _: &OperationContext, _: &str, _: OpPresign) -> Result<RpPresign> {
Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
))
}
}