Skip to main content

object_store/layers/
mock.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt::Debug;
16use std::sync::Arc;
17
18use derive_builder::Builder;
19pub use oio::*;
20pub use opendal::raw::{
21    Layer, OpCopy, OpDelete, OpList, OpRead, OpWrite, RpRead, Service, Servicer, oio,
22};
23pub use opendal::{Buffer, BytesRange, Error, ErrorKind, Metadata, OperationContext, Result};
24
25pub type MockWriterFactory = Arc<dyn Fn(&str, OpWrite, oio::Writer) -> oio::Writer + Send + Sync>;
26pub type MockReaderFactory = Arc<dyn Fn(&str, OpRead, oio::Reader) -> oio::Reader + Send + Sync>;
27pub type MockListerFactory = Arc<dyn Fn(&str, OpList, oio::Lister) -> oio::Lister + Send + Sync>;
28pub type MockDeleterFactory = Arc<dyn Fn(oio::Deleter) -> oio::Deleter + Send + Sync>;
29pub type CopyInterceptor = Arc<dyn Fn(&str, &str, OpCopy) -> Option<Result<()>> + Send + Sync>;
30
31#[derive(Builder)]
32pub struct MockLayer {
33    #[builder(setter(strip_option), default)]
34    writer_factory: Option<MockWriterFactory>,
35    #[builder(setter(strip_option), default)]
36    reader_factory: Option<MockReaderFactory>,
37    #[builder(setter(strip_option), default)]
38    lister_factory: Option<MockListerFactory>,
39    #[builder(setter(strip_option), default)]
40    deleter_factory: Option<MockDeleterFactory>,
41    #[builder(setter(strip_option), default)]
42    copy_interceptor: Option<CopyInterceptor>,
43}
44
45impl Clone for MockLayer {
46    fn clone(&self) -> Self {
47        Self {
48            writer_factory: self.writer_factory.clone(),
49            reader_factory: self.reader_factory.clone(),
50            lister_factory: self.lister_factory.clone(),
51            deleter_factory: self.deleter_factory.clone(),
52            copy_interceptor: self.copy_interceptor.clone(),
53        }
54    }
55}
56
57impl Debug for MockLayer {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        f.debug_struct("MockLayer").finish_non_exhaustive()
60    }
61}
62
63impl Layer for MockLayer {
64    fn apply_service(&self, inner: Servicer) -> Servicer {
65        Arc::new(MockService {
66            inner,
67            writer_factory: self.writer_factory.clone(),
68            reader_factory: self.reader_factory.clone(),
69            lister_factory: self.lister_factory.clone(),
70            deleter_factory: self.deleter_factory.clone(),
71            copy_interceptor: self.copy_interceptor.clone(),
72        })
73    }
74}
75
76struct MockService {
77    inner: Servicer,
78    writer_factory: Option<MockWriterFactory>,
79    reader_factory: Option<MockReaderFactory>,
80    lister_factory: Option<MockListerFactory>,
81    deleter_factory: Option<MockDeleterFactory>,
82    copy_interceptor: Option<CopyInterceptor>,
83}
84
85impl Debug for MockService {
86    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87        f.debug_struct("MockService")
88            .field("inner", &self.inner)
89            .finish_non_exhaustive()
90    }
91}
92
93impl Service for MockService {
94    type Reader = oio::Reader;
95    type Writer = oio::Writer;
96    type Lister = oio::Lister;
97    type Deleter = oio::Deleter;
98    type Copier = oio::Copier;
99    type Composer = oio::Composer;
100
101    fn info(&self) -> opendal::raw::ServiceInfo {
102        self.inner.info()
103    }
104
105    fn capability(&self) -> opendal::Capability {
106        self.inner.capability()
107    }
108
109    async fn create_dir(
110        &self,
111        ctx: &OperationContext,
112        path: &str,
113        args: opendal::raw::OpCreateDir,
114    ) -> Result<opendal::raw::RpCreateDir> {
115        self.inner.create_dir(ctx, path, args).await
116    }
117
118    async fn stat(
119        &self,
120        ctx: &OperationContext,
121        path: &str,
122        args: opendal::raw::OpStat,
123    ) -> Result<opendal::raw::RpStat> {
124        self.inner.stat(ctx, path, args).await
125    }
126
127    fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
128        let reader = self.inner.read(ctx, path, args.clone())?;
129        if let Some(reader_factory) = self.reader_factory.as_ref() {
130            Ok(reader_factory(path, args, reader))
131        } else {
132            Ok(reader)
133        }
134    }
135
136    fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<Self::Writer> {
137        let writer = self.inner.write(ctx, path, args.clone())?;
138        if let Some(writer_factory) = self.writer_factory.as_ref() {
139            Ok(writer_factory(path, args, writer))
140        } else {
141            Ok(writer)
142        }
143    }
144
145    fn delete(&self, ctx: &OperationContext) -> Result<Self::Deleter> {
146        let deleter = self.inner.delete(ctx)?;
147        if let Some(deleter_factory) = self.deleter_factory.as_ref() {
148            Ok(deleter_factory(deleter))
149        } else {
150            Ok(deleter)
151        }
152    }
153
154    fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<Self::Lister> {
155        let lister = self.inner.list(ctx, path, args.clone())?;
156        if let Some(lister_factory) = self.lister_factory.as_ref() {
157            Ok(lister_factory(path, args, lister))
158        } else {
159            Ok(lister)
160        }
161    }
162
163    fn copy(
164        &self,
165        ctx: &OperationContext,
166        from: &str,
167        to: &str,
168        args: OpCopy,
169    ) -> Result<Self::Copier> {
170        if let Some(result) = self
171            .copy_interceptor
172            .as_ref()
173            .and_then(|copy_interceptor| copy_interceptor(from, to, args.clone()))
174        {
175            result?;
176            return Ok(Box::new(oio::OneShotCopier::completed()) as oio::Copier);
177        }
178
179        self.inner.copy(ctx, from, to, args)
180    }
181
182    fn compose(
183        &self,
184        ctx: &OperationContext,
185        to: &str,
186        args: opendal::raw::OpCompose,
187    ) -> Result<Self::Composer> {
188        self.inner.compose(ctx, to, args)
189    }
190
191    async fn rename(
192        &self,
193        ctx: &OperationContext,
194        from: &str,
195        to: &str,
196        args: opendal::raw::OpRename,
197    ) -> Result<opendal::raw::RpRename> {
198        self.inner.rename(ctx, from, to, args).await
199    }
200
201    async fn presign(
202        &self,
203        ctx: &OperationContext,
204        path: &str,
205        args: opendal::raw::OpPresign,
206    ) -> Result<opendal::raw::RpPresign> {
207        self.inner.presign(ctx, path, args).await
208    }
209}
210
211pub struct MockReader {
212    inner: oio::Reader,
213}
214
215impl oio::Read for MockReader {
216    async fn open(
217        &self,
218        range: opendal::BytesRange,
219    ) -> Result<(opendal::raw::RpRead, Box<dyn oio::ReadStreamDyn>)> {
220        self.inner.open(range).await
221    }
222
223    async fn read(&self, range: opendal::BytesRange) -> Result<(opendal::raw::RpRead, Buffer)> {
224        self.inner.read(range).await
225    }
226}
227
228pub struct MockWriter {
229    inner: oio::Writer,
230}
231
232impl oio::Write for MockWriter {
233    async fn write(&mut self, bs: Buffer) -> Result<()> {
234        self.inner.write(bs).await
235    }
236
237    async fn close(&mut self) -> Result<Metadata> {
238        self.inner.close().await
239    }
240
241    async fn abort(&mut self) -> Result<()> {
242        self.inner.abort().await
243    }
244}
245
246pub struct MockLister {
247    inner: oio::Lister,
248}
249
250impl oio::List for MockLister {
251    async fn next(&mut self) -> Result<Option<oio::Entry>> {
252        self.inner.next().await
253    }
254}
255
256pub struct MockDeleter {
257    inner: oio::Deleter,
258}
259
260impl oio::Delete for MockDeleter {
261    async fn delete(&mut self, path: &str, args: OpDelete) -> Result<()> {
262        self.inner.delete(path, args).await
263    }
264
265    async fn close(&mut self) -> Result<()> {
266        self.inner.close().await
267    }
268}