Trait opendal::raw::Layer

source ·
pub trait Layer<A: Accessor> {
    type LayeredAccessor: Accessor;

    // Required method
    fn layer(&self, inner: A) -> Self::LayeredAccessor;
}
Expand description

Layer is used to intercept the operations on the underlying storage.

Struct that implement this trait must accept input Arc<dyn Accessor> as inner, and returns a new Arc<dyn Accessor> as output.

All functions in Accessor requires &self, so it’s implementor’s responsibility to maintain the internal mutability. Please also keep in mind that Accessor requires Send and Sync.

Notes

Inner

It’s required to implement fn inner() -> Option<Arc<dyn Accessor>> for layer’s accessors.

By implement this method, all API calls will be forwarded to inner accessor instead.

Examples

use std::sync::Arc;

use async_trait::async_trait;
use opendal::ops::*;
use opendal::raw::*;
use opendal::*;

/// Implement the real accessor logic here.
#[derive(Debug)]
struct TraceAccessor<A: Accessor> {
    inner: A,
}

#[async_trait]
impl<A: Accessor> LayeredAccessor for TraceAccessor<A> {
    type Inner = A;
    type Reader = A::Reader;
    type BlockingReader = A::BlockingReader;
    type Writer = A::Writer;
    type BlockingWriter = A::BlockingWriter;
    type Pager = A::Pager;
    type BlockingPager = A::BlockingPager;

    fn inner(&self) -> &Self::Inner {
        &self.inner
    }

    async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> {
        self.inner.read(path, args).await
    }

    fn blocking_read(
        &self,
        path: &str,
        args: OpRead,
    ) -> Result<(RpRead, Self::BlockingReader)> {
        self.inner.blocking_read(path, args)
    }

    async fn write(&self, path: &str, args: OpWrite) -> Result<(RpWrite, Self::Writer)> {
        self.inner.write(path, args).await
    }

    fn blocking_write(
        &self,
        path: &str,
        args: OpWrite,
    ) -> Result<(RpWrite, Self::BlockingWriter)> {
        self.inner.blocking_write(path, args)
    }

    async fn list(&self, path: &str, args: OpList) -> Result<(RpList, Self::Pager)> {
        self.inner.list(path, args).await
    }

    fn blocking_list(&self, path: &str, args: OpList) -> Result<(RpList, Self::BlockingPager)> {
        self.inner.blocking_list(path, args)
    }

    async fn scan(&self, path: &str, args: OpScan) -> Result<(RpScan, Self::Pager)> {
        self.inner.scan(path, args).await
    }

    fn blocking_scan(&self, path: &str, args: OpScan) -> Result<(RpScan, Self::BlockingPager)> {
        self.inner.blocking_scan(path, args)
    }
}

/// The public struct that exposed to users.
///
/// Will be used like `op.layer(TraceLayer)`
struct TraceLayer;

impl<A: Accessor> Layer<A> for TraceLayer {
    type LayeredAccessor = TraceAccessor<A>;

    fn layer(&self, inner: A) -> Self::LayeredAccessor {
        TraceAccessor { inner }
    }
}

Required Associated Types§

source

type LayeredAccessor: Accessor

The layered accessor that return by this layer.

Required Methods§

source

fn layer(&self, inner: A) -> Self::LayeredAccessor

Intercept the operations on the underlying storage.

Implementors§

source§

impl<A: Accessor> Layer<A> for ChaosLayer

§

type LayeredAccessor = ChaosAccessor<A>

source§

impl<A: Accessor> Layer<A> for ConcurrentLimitLayer

§

type LayeredAccessor = ConcurrentLimitAccessor<A>

source§

impl<A: Accessor> Layer<A> for ImmutableIndexLayer

§

type LayeredAccessor = ImmutableIndexAccessor<A>

source§

impl<A: Accessor> Layer<A> for LoggingLayer

§

type LayeredAccessor = LoggingAccessor<A>

source§

impl<A: Accessor> Layer<A> for MetricsLayer

§

type LayeredAccessor = MetricsAccessor<A>

source§

impl<A: Accessor> Layer<A> for RetryLayer

§

type LayeredAccessor = RetryAccessor<A>

source§

impl<A: Accessor> Layer<A> for TracingLayer

§

type LayeredAccessor = TracingAccessor<A>