1use std::fmt::Debug;
19use std::future::Future;
20use std::sync::Arc;
21
22use crate::raw::*;
23use crate::*;
24
25#[derive(Clone, PartialEq, Eq, Hash)]
30pub struct ServiceInfo {
31 scheme: &'static str,
32 root: Arc<str>,
33 name: Arc<str>,
34}
35
36impl Debug for ServiceInfo {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 f.debug_struct("ServiceInfo")
39 .field("scheme", &self.scheme())
40 .field("root", &self.root())
41 .field("name", &self.name())
42 .finish_non_exhaustive()
43 }
44}
45
46impl ServiceInfo {
47 pub fn new(scheme: &'static str, root: impl AsRef<str>, name: impl AsRef<str>) -> Self {
49 Self {
50 scheme,
51 root: Arc::from(root.as_ref()),
52 name: Arc::from(name.as_ref()),
53 }
54 }
55
56 pub fn with_scheme(scheme: &'static str) -> Self {
58 Self::new(scheme, "", "")
59 }
60
61 pub fn with_root(&self, root: impl AsRef<str>) -> Self {
63 Self {
64 scheme: self.scheme,
65 root: Arc::from(root.as_ref()),
66 name: self.name.clone(),
67 }
68 }
69
70 pub fn scheme(&self) -> &'static str {
72 self.scheme
73 }
74
75 pub fn root(&self) -> Arc<str> {
77 self.root.clone()
78 }
79
80 pub fn name(&self) -> Arc<str> {
89 self.name.clone()
90 }
91}
92
93pub trait Service: Send + Sync + Debug + Unpin + 'static {
109 type Reader: oio::Read;
111 type Writer: oio::Write;
113 type Lister: oio::List;
115 type Deleter: oio::Delete;
117 type Copier: oio::Copy;
119
120 fn info(&self) -> ServiceInfo;
122
123 fn capability(&self) -> Capability;
128
129 fn create_dir(
138 &self,
139 ctx: &OperationContext,
140 path: &str,
141 args: OpCreateDir,
142 ) -> impl Future<Output = Result<RpCreateDir>> + MaybeSend;
143
144 fn stat(
154 &self,
155 ctx: &OperationContext,
156 path: &str,
157 args: OpStat,
158 ) -> impl Future<Output = Result<RpStat>> + MaybeSend;
159
160 fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader>;
169
170 fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<Self::Writer>;
178
179 fn delete(&self, ctx: &OperationContext) -> Result<Self::Deleter>;
188
189 fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<Self::Lister>;
198
199 fn copy(
208 &self,
209 ctx: &OperationContext,
210 from: &str,
211 to: &str,
212 args: OpCopy,
213 opts: OpCopier,
214 ) -> Result<Self::Copier>;
215
216 fn rename(
224 &self,
225 ctx: &OperationContext,
226 from: &str,
227 to: &str,
228 args: OpRename,
229 ) -> impl Future<Output = Result<RpRename>> + MaybeSend;
230
231 fn presign(
236 &self,
237 ctx: &OperationContext,
238 path: &str,
239 args: OpPresign,
240 ) -> impl Future<Output = Result<RpPresign>> + MaybeSend;
241}
242
243pub trait ServiceDyn: Send + Sync + Debug + Unpin + 'static {
245 fn info_dyn(&self) -> ServiceInfo;
247
248 fn capability_dyn(&self) -> Capability;
250
251 fn create_dir_dyn<'a>(
253 &'a self,
254 ctx: &'a OperationContext,
255 path: &'a str,
256 args: OpCreateDir,
257 ) -> BoxedFuture<'a, Result<RpCreateDir>>;
258
259 fn stat_dyn<'a>(
261 &'a self,
262 ctx: &'a OperationContext,
263 path: &'a str,
264 args: OpStat,
265 ) -> BoxedFuture<'a, Result<RpStat>>;
266
267 fn read_dyn<'a>(
269 &'a self,
270 ctx: &'a OperationContext,
271 path: &'a str,
272 args: OpRead,
273 ) -> Result<oio::Reader>;
274
275 fn write_dyn<'a>(
277 &'a self,
278 ctx: &'a OperationContext,
279 path: &'a str,
280 args: OpWrite,
281 ) -> Result<oio::Writer>;
282
283 fn delete_dyn<'a>(&'a self, ctx: &'a OperationContext) -> Result<oio::Deleter>;
285
286 fn list_dyn<'a>(
288 &'a self,
289 ctx: &'a OperationContext,
290 path: &'a str,
291 args: OpList,
292 ) -> Result<oio::Lister>;
293
294 fn copy_dyn<'a>(
296 &'a self,
297 ctx: &'a OperationContext,
298 from: &'a str,
299 to: &'a str,
300 args: OpCopy,
301 opts: OpCopier,
302 ) -> Result<oio::Copier>;
303
304 fn rename_dyn<'a>(
306 &'a self,
307 ctx: &'a OperationContext,
308 from: &'a str,
309 to: &'a str,
310 args: OpRename,
311 ) -> BoxedFuture<'a, Result<RpRename>>;
312
313 fn presign_dyn<'a>(
315 &'a self,
316 ctx: &'a OperationContext,
317 path: &'a str,
318 args: OpPresign,
319 ) -> BoxedFuture<'a, Result<RpPresign>>;
320}
321
322pub type Servicer = Arc<dyn ServiceDyn>;
324
325impl<S: Service + ?Sized> ServiceDyn for S {
326 fn info_dyn(&self) -> ServiceInfo {
327 self.info()
328 }
329
330 fn capability_dyn(&self) -> Capability {
331 self.capability()
332 }
333
334 fn create_dir_dyn<'a>(
335 &'a self,
336 ctx: &'a OperationContext,
337 path: &'a str,
338 args: OpCreateDir,
339 ) -> BoxedFuture<'a, Result<RpCreateDir>> {
340 Box::pin(self.create_dir(ctx, path, args))
341 }
342
343 fn stat_dyn<'a>(
344 &'a self,
345 ctx: &'a OperationContext,
346 path: &'a str,
347 args: OpStat,
348 ) -> BoxedFuture<'a, Result<RpStat>> {
349 Box::pin(self.stat(ctx, path, args))
350 }
351
352 fn read_dyn<'a>(
353 &'a self,
354 ctx: &'a OperationContext,
355 path: &'a str,
356 args: OpRead,
357 ) -> Result<oio::Reader> {
358 Ok(Box::new(self.read(ctx, path, args)?) as oio::Reader)
359 }
360
361 fn write_dyn<'a>(
362 &'a self,
363 ctx: &'a OperationContext,
364 path: &'a str,
365 args: OpWrite,
366 ) -> Result<oio::Writer> {
367 Ok(Box::new(self.write(ctx, path, args)?) as oio::Writer)
368 }
369
370 fn delete_dyn<'a>(&'a self, ctx: &'a OperationContext) -> Result<oio::Deleter> {
371 Ok(Box::new(self.delete(ctx)?) as oio::Deleter)
372 }
373
374 fn list_dyn<'a>(
375 &'a self,
376 ctx: &'a OperationContext,
377 path: &'a str,
378 args: OpList,
379 ) -> Result<oio::Lister> {
380 Ok(Box::new(self.list(ctx, path, args)?) as oio::Lister)
381 }
382
383 fn copy_dyn<'a>(
384 &'a self,
385 ctx: &'a OperationContext,
386 from: &'a str,
387 to: &'a str,
388 args: OpCopy,
389 opts: OpCopier,
390 ) -> Result<oio::Copier> {
391 Ok(Box::new(self.copy(ctx, from, to, args, opts)?) as oio::Copier)
392 }
393
394 fn rename_dyn<'a>(
395 &'a self,
396 ctx: &'a OperationContext,
397 from: &'a str,
398 to: &'a str,
399 args: OpRename,
400 ) -> BoxedFuture<'a, Result<RpRename>> {
401 Box::pin(self.rename(ctx, from, to, args))
402 }
403
404 fn presign_dyn<'a>(
405 &'a self,
406 ctx: &'a OperationContext,
407 path: &'a str,
408 args: OpPresign,
409 ) -> BoxedFuture<'a, Result<RpPresign>> {
410 Box::pin(self.presign(ctx, path, args))
411 }
412}
413
414impl<T: ServiceDyn + ?Sized> Service for Arc<T> {
416 type Reader = oio::Reader;
417 type Writer = oio::Writer;
418 type Lister = oio::Lister;
419 type Deleter = oio::Deleter;
420 type Copier = oio::Copier;
421
422 fn info(&self) -> ServiceInfo {
423 self.as_ref().info_dyn()
424 }
425
426 fn capability(&self) -> Capability {
427 self.as_ref().capability_dyn()
428 }
429
430 async fn create_dir(
431 &self,
432 ctx: &OperationContext,
433 path: &str,
434 args: OpCreateDir,
435 ) -> Result<RpCreateDir> {
436 self.as_ref().create_dir_dyn(ctx, path, args).await
437 }
438
439 async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
440 self.as_ref().stat_dyn(ctx, path, args).await
441 }
442
443 fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<oio::Reader> {
444 self.as_ref().read_dyn(ctx, path, args)
445 }
446
447 fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<oio::Writer> {
448 self.as_ref().write_dyn(ctx, path, args)
449 }
450
451 fn delete(&self, ctx: &OperationContext) -> Result<oio::Deleter> {
452 self.as_ref().delete_dyn(ctx)
453 }
454
455 fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<oio::Lister> {
456 self.as_ref().list_dyn(ctx, path, args)
457 }
458
459 fn copy(
460 &self,
461 ctx: &OperationContext,
462 from: &str,
463 to: &str,
464 args: OpCopy,
465 opts: OpCopier,
466 ) -> Result<oio::Copier> {
467 self.as_ref().copy_dyn(ctx, from, to, args, opts)
468 }
469
470 async fn rename(
471 &self,
472 ctx: &OperationContext,
473 from: &str,
474 to: &str,
475 args: OpRename,
476 ) -> Result<RpRename> {
477 self.as_ref().rename_dyn(ctx, from, to, args).await
478 }
479
480 async fn presign(
481 &self,
482 ctx: &OperationContext,
483 path: &str,
484 args: OpPresign,
485 ) -> Result<RpPresign> {
486 self.as_ref().presign_dyn(ctx, path, args).await
487 }
488}
489
490impl Service for () {
492 type Reader = ();
493 type Writer = ();
494 type Lister = ();
495 type Deleter = ();
496 type Copier = ();
497
498 fn info(&self) -> ServiceInfo {
499 ServiceInfo::with_scheme("dummy")
500 }
501
502 fn capability(&self) -> Capability {
503 Capability::default()
504 }
505
506 async fn create_dir(
507 &self,
508 _: &OperationContext,
509 _: &str,
510 _: OpCreateDir,
511 ) -> Result<RpCreateDir> {
512 Err(Error::new(
513 ErrorKind::Unsupported,
514 "operation is not supported",
515 ))
516 }
517
518 async fn stat(&self, _: &OperationContext, _: &str, _: OpStat) -> Result<RpStat> {
519 Err(Error::new(
520 ErrorKind::Unsupported,
521 "operation is not supported",
522 ))
523 }
524
525 fn read(&self, _: &OperationContext, _: &str, _: OpRead) -> Result<Self::Reader> {
526 Err(Error::new(
527 ErrorKind::Unsupported,
528 "operation is not supported",
529 ))
530 }
531
532 fn write(&self, _: &OperationContext, _: &str, _: OpWrite) -> Result<Self::Writer> {
533 Err(Error::new(
534 ErrorKind::Unsupported,
535 "operation is not supported",
536 ))
537 }
538
539 fn delete(&self, _: &OperationContext) -> Result<Self::Deleter> {
540 Err(Error::new(
541 ErrorKind::Unsupported,
542 "operation is not supported",
543 ))
544 }
545
546 fn list(&self, _: &OperationContext, _: &str, _: OpList) -> Result<Self::Lister> {
547 Err(Error::new(
548 ErrorKind::Unsupported,
549 "operation is not supported",
550 ))
551 }
552
553 fn copy(
554 &self,
555 _: &OperationContext,
556 _: &str,
557 _: &str,
558 _: OpCopy,
559 _: OpCopier,
560 ) -> Result<Self::Copier> {
561 Err(Error::new(
562 ErrorKind::Unsupported,
563 "operation is not supported",
564 ))
565 }
566
567 async fn rename(
568 &self,
569 _: &OperationContext,
570 _: &str,
571 _: &str,
572 _: OpRename,
573 ) -> Result<RpRename> {
574 Err(Error::new(
575 ErrorKind::Unsupported,
576 "operation is not supported",
577 ))
578 }
579
580 async fn presign(&self, _: &OperationContext, _: &str, _: OpPresign) -> Result<RpPresign> {
581 Err(Error::new(
582 ErrorKind::Unsupported,
583 "operation is not supported",
584 ))
585 }
586}