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 {
110 type Reader: oio::Read;
112 type Writer: oio::Write;
114 type Lister: oio::List;
116 type Deleter: oio::Delete;
118 type Copier: oio::Copy;
120
121 fn info(&self) -> ServiceInfo;
123
124 fn capability(&self) -> Capability;
130
131 fn create_dir(
140 &self,
141 ctx: &OperationContext,
142 path: &str,
143 args: OpCreateDir,
144 ) -> impl Future<Output = Result<RpCreateDir>> + MaybeSend;
145
146 fn stat(
156 &self,
157 ctx: &OperationContext,
158 path: &str,
159 args: OpStat,
160 ) -> impl Future<Output = Result<RpStat>> + MaybeSend;
161
162 fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader>;
171
172 fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<Self::Writer>;
180
181 fn delete(&self, ctx: &OperationContext) -> Result<Self::Deleter>;
190
191 fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<Self::Lister>;
200
201 fn copy(
210 &self,
211 ctx: &OperationContext,
212 from: &str,
213 to: &str,
214 args: OpCopy,
215 opts: OpCopier,
216 ) -> Result<Self::Copier>;
217
218 fn rename(
226 &self,
227 ctx: &OperationContext,
228 from: &str,
229 to: &str,
230 args: OpRename,
231 ) -> impl Future<Output = Result<RpRename>> + MaybeSend;
232
233 fn presign(
238 &self,
239 ctx: &OperationContext,
240 path: &str,
241 args: OpPresign,
242 ) -> impl Future<Output = Result<RpPresign>> + MaybeSend;
243}
244
245pub trait ServiceDyn: Send + Sync + Debug + Unpin + 'static {
247 fn info_dyn(&self) -> ServiceInfo;
249
250 fn capability_dyn(&self) -> Capability;
252
253 fn create_dir_dyn<'a>(
255 &'a self,
256 ctx: &'a OperationContext,
257 path: &'a str,
258 args: OpCreateDir,
259 ) -> BoxedFuture<'a, Result<RpCreateDir>>;
260
261 fn stat_dyn<'a>(
263 &'a self,
264 ctx: &'a OperationContext,
265 path: &'a str,
266 args: OpStat,
267 ) -> BoxedFuture<'a, Result<RpStat>>;
268
269 fn read_dyn<'a>(
271 &'a self,
272 ctx: &'a OperationContext,
273 path: &'a str,
274 args: OpRead,
275 ) -> Result<oio::Reader>;
276
277 fn write_dyn<'a>(
279 &'a self,
280 ctx: &'a OperationContext,
281 path: &'a str,
282 args: OpWrite,
283 ) -> Result<oio::Writer>;
284
285 fn delete_dyn<'a>(&'a self, ctx: &'a OperationContext) -> Result<oio::Deleter>;
287
288 fn list_dyn<'a>(
290 &'a self,
291 ctx: &'a OperationContext,
292 path: &'a str,
293 args: OpList,
294 ) -> Result<oio::Lister>;
295
296 fn copy_dyn<'a>(
298 &'a self,
299 ctx: &'a OperationContext,
300 from: &'a str,
301 to: &'a str,
302 args: OpCopy,
303 opts: OpCopier,
304 ) -> Result<oio::Copier>;
305
306 fn rename_dyn<'a>(
308 &'a self,
309 ctx: &'a OperationContext,
310 from: &'a str,
311 to: &'a str,
312 args: OpRename,
313 ) -> BoxedFuture<'a, Result<RpRename>>;
314
315 fn presign_dyn<'a>(
317 &'a self,
318 ctx: &'a OperationContext,
319 path: &'a str,
320 args: OpPresign,
321 ) -> BoxedFuture<'a, Result<RpPresign>>;
322}
323
324pub type Servicer = Arc<dyn ServiceDyn>;
326
327impl<S: Service + ?Sized> ServiceDyn for S {
328 fn info_dyn(&self) -> ServiceInfo {
329 self.info()
330 }
331
332 fn capability_dyn(&self) -> Capability {
333 self.capability()
334 }
335
336 fn create_dir_dyn<'a>(
337 &'a self,
338 ctx: &'a OperationContext,
339 path: &'a str,
340 args: OpCreateDir,
341 ) -> BoxedFuture<'a, Result<RpCreateDir>> {
342 Box::pin(self.create_dir(ctx, path, args))
343 }
344
345 fn stat_dyn<'a>(
346 &'a self,
347 ctx: &'a OperationContext,
348 path: &'a str,
349 args: OpStat,
350 ) -> BoxedFuture<'a, Result<RpStat>> {
351 Box::pin(self.stat(ctx, path, args))
352 }
353
354 fn read_dyn<'a>(
355 &'a self,
356 ctx: &'a OperationContext,
357 path: &'a str,
358 args: OpRead,
359 ) -> Result<oio::Reader> {
360 Ok(Box::new(self.read(ctx, path, args)?) as oio::Reader)
361 }
362
363 fn write_dyn<'a>(
364 &'a self,
365 ctx: &'a OperationContext,
366 path: &'a str,
367 args: OpWrite,
368 ) -> Result<oio::Writer> {
369 Ok(Box::new(self.write(ctx, path, args)?) as oio::Writer)
370 }
371
372 fn delete_dyn<'a>(&'a self, ctx: &'a OperationContext) -> Result<oio::Deleter> {
373 Ok(Box::new(self.delete(ctx)?) as oio::Deleter)
374 }
375
376 fn list_dyn<'a>(
377 &'a self,
378 ctx: &'a OperationContext,
379 path: &'a str,
380 args: OpList,
381 ) -> Result<oio::Lister> {
382 Ok(Box::new(self.list(ctx, path, args)?) as oio::Lister)
383 }
384
385 fn copy_dyn<'a>(
386 &'a self,
387 ctx: &'a OperationContext,
388 from: &'a str,
389 to: &'a str,
390 args: OpCopy,
391 opts: OpCopier,
392 ) -> Result<oio::Copier> {
393 Ok(Box::new(self.copy(ctx, from, to, args, opts)?) as oio::Copier)
394 }
395
396 fn rename_dyn<'a>(
397 &'a self,
398 ctx: &'a OperationContext,
399 from: &'a str,
400 to: &'a str,
401 args: OpRename,
402 ) -> BoxedFuture<'a, Result<RpRename>> {
403 Box::pin(self.rename(ctx, from, to, args))
404 }
405
406 fn presign_dyn<'a>(
407 &'a self,
408 ctx: &'a OperationContext,
409 path: &'a str,
410 args: OpPresign,
411 ) -> BoxedFuture<'a, Result<RpPresign>> {
412 Box::pin(self.presign(ctx, path, args))
413 }
414}
415
416impl<T: ServiceDyn + ?Sized> Service for Arc<T> {
418 type Reader = oio::Reader;
419 type Writer = oio::Writer;
420 type Lister = oio::Lister;
421 type Deleter = oio::Deleter;
422 type Copier = oio::Copier;
423
424 fn info(&self) -> ServiceInfo {
425 self.as_ref().info_dyn()
426 }
427
428 fn capability(&self) -> Capability {
429 self.as_ref().capability_dyn()
430 }
431
432 async fn create_dir(
433 &self,
434 ctx: &OperationContext,
435 path: &str,
436 args: OpCreateDir,
437 ) -> Result<RpCreateDir> {
438 self.as_ref().create_dir_dyn(ctx, path, args).await
439 }
440
441 async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
442 self.as_ref().stat_dyn(ctx, path, args).await
443 }
444
445 fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<oio::Reader> {
446 self.as_ref().read_dyn(ctx, path, args)
447 }
448
449 fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<oio::Writer> {
450 self.as_ref().write_dyn(ctx, path, args)
451 }
452
453 fn delete(&self, ctx: &OperationContext) -> Result<oio::Deleter> {
454 self.as_ref().delete_dyn(ctx)
455 }
456
457 fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<oio::Lister> {
458 self.as_ref().list_dyn(ctx, path, args)
459 }
460
461 fn copy(
462 &self,
463 ctx: &OperationContext,
464 from: &str,
465 to: &str,
466 args: OpCopy,
467 opts: OpCopier,
468 ) -> Result<oio::Copier> {
469 self.as_ref().copy_dyn(ctx, from, to, args, opts)
470 }
471
472 async fn rename(
473 &self,
474 ctx: &OperationContext,
475 from: &str,
476 to: &str,
477 args: OpRename,
478 ) -> Result<RpRename> {
479 self.as_ref().rename_dyn(ctx, from, to, args).await
480 }
481
482 async fn presign(
483 &self,
484 ctx: &OperationContext,
485 path: &str,
486 args: OpPresign,
487 ) -> Result<RpPresign> {
488 self.as_ref().presign_dyn(ctx, path, args).await
489 }
490}
491
492impl Service for () {
494 type Reader = ();
495 type Writer = ();
496 type Lister = ();
497 type Deleter = ();
498 type Copier = ();
499
500 fn info(&self) -> ServiceInfo {
501 ServiceInfo::with_scheme("dummy")
502 }
503
504 fn capability(&self) -> Capability {
505 Capability::default()
506 }
507
508 async fn create_dir(
509 &self,
510 _: &OperationContext,
511 _: &str,
512 _: OpCreateDir,
513 ) -> Result<RpCreateDir> {
514 Err(Error::new(
515 ErrorKind::Unsupported,
516 "operation is not supported",
517 ))
518 }
519
520 async fn stat(&self, _: &OperationContext, _: &str, _: OpStat) -> Result<RpStat> {
521 Err(Error::new(
522 ErrorKind::Unsupported,
523 "operation is not supported",
524 ))
525 }
526
527 fn read(&self, _: &OperationContext, _: &str, _: OpRead) -> Result<Self::Reader> {
528 Err(Error::new(
529 ErrorKind::Unsupported,
530 "operation is not supported",
531 ))
532 }
533
534 fn write(&self, _: &OperationContext, _: &str, _: OpWrite) -> Result<Self::Writer> {
535 Err(Error::new(
536 ErrorKind::Unsupported,
537 "operation is not supported",
538 ))
539 }
540
541 fn delete(&self, _: &OperationContext) -> Result<Self::Deleter> {
542 Err(Error::new(
543 ErrorKind::Unsupported,
544 "operation is not supported",
545 ))
546 }
547
548 fn list(&self, _: &OperationContext, _: &str, _: OpList) -> Result<Self::Lister> {
549 Err(Error::new(
550 ErrorKind::Unsupported,
551 "operation is not supported",
552 ))
553 }
554
555 fn copy(
556 &self,
557 _: &OperationContext,
558 _: &str,
559 _: &str,
560 _: OpCopy,
561 _: OpCopier,
562 ) -> Result<Self::Copier> {
563 Err(Error::new(
564 ErrorKind::Unsupported,
565 "operation is not supported",
566 ))
567 }
568
569 async fn rename(
570 &self,
571 _: &OperationContext,
572 _: &str,
573 _: &str,
574 _: OpRename,
575 ) -> Result<RpRename> {
576 Err(Error::new(
577 ErrorKind::Unsupported,
578 "operation is not supported",
579 ))
580 }
581
582 async fn presign(&self, _: &OperationContext, _: &str, _: OpPresign) -> Result<RpPresign> {
583 Err(Error::new(
584 ErrorKind::Unsupported,
585 "operation is not supported",
586 ))
587 }
588}