This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch polish-details
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git

commit 964d1c9d3267bc84749cc49eb1a30b4c9e898c52
Author: Xuanwo <[email protected]>
AuthorDate: Thu Sep 14 15:40:52 2023 +0800

    polish
    
    Signed-off-by: Xuanwo <[email protected]>
---
 core/src/layers/complete.rs  | 231 +++++++++++++++++++++++++++----------------
 core/src/raw/oio/page/api.rs |   9 +-
 2 files changed, 152 insertions(+), 88 deletions(-)

diff --git a/core/src/layers/complete.rs b/core/src/layers/complete.rs
index f3c617912..776d847c9 100644
--- a/core/src/layers/complete.rs
+++ b/core/src/layers/complete.rs
@@ -794,42 +794,13 @@ where
 
 #[cfg(test)]
 mod tests {
-    use std::collections::HashMap;
-    use std::time::Duration;
-
     use async_trait::async_trait;
     use http::HeaderMap;
     use http::Method as HttpMethod;
+    use std::time::Duration;
 
     use super::*;
 
-    #[derive(Default)]
-    struct MockBuilder {
-        capability: Capability,
-    }
-
-    impl MockBuilder {
-        fn with_capacity(mut self, capability: Capability) -> Self {
-            self.capability = capability;
-            self
-        }
-    }
-
-    impl Builder for MockBuilder {
-        const SCHEME: Scheme = Scheme::Custom("mock");
-        type Accessor = MockService;
-
-        fn from_map(_: HashMap<String, String>) -> Self {
-            Self::default()
-        }
-
-        fn build(&mut self) -> Result<Self::Accessor> {
-            Ok(MockService {
-                capability: self.capability,
-            })
-        }
-    }
-
     #[derive(Debug)]
     struct MockService {
         capability: Capability,
@@ -837,12 +808,12 @@ mod tests {
 
     #[async_trait]
     impl Accessor for MockService {
-        type Reader = ();
-        type BlockingReader = ();
-        type Writer = ();
-        type BlockingWriter = ();
-        type Pager = ();
-        type BlockingPager = ();
+        type Reader = oio::Reader;
+        type BlockingReader = oio::BlockingReader;
+        type Writer = oio::Writer;
+        type BlockingWriter = oio::BlockingWriter;
+        type Pager = oio::Pager;
+        type BlockingPager = oio::BlockingPager;
 
         fn info(&self) -> AccessorInfo {
             let mut info = AccessorInfo::default();
@@ -856,11 +827,11 @@ mod tests {
         }
 
         async fn read(&self, _: &str, _: OpRead) -> Result<(RpRead, 
Self::Reader)> {
-            Ok((RpRead::new(0), ()))
+            Ok((RpRead::new(0), Box::new(())))
         }
 
         async fn write(&self, _: &str, _: OpWrite) -> Result<(RpWrite, 
Self::Writer)> {
-            Ok((RpWrite::new(), ()))
+            Ok((RpWrite::new(), Box::new(())))
         }
 
         async fn copy(&self, _: &str, _: &str, _: OpCopy) -> Result<RpCopy> {
@@ -880,7 +851,7 @@ mod tests {
         }
 
         async fn list(&self, _: &str, _: OpList) -> Result<(RpList, 
Self::Pager)> {
-            Ok((RpList {}, ()))
+            Ok((RpList {}, Box::new(())))
         }
 
         async fn presign(&self, _: &str, _: OpPresign) -> Result<RpPresign> {
@@ -892,50 +863,144 @@ mod tests {
         }
     }
 
-    /// Perform the test against different capability preconditions.
-    macro_rules! capability_test {
-        ($cap:ident, |$arg:ident| { $($body:tt)* }) => {
-            paste::item! {
-                #[tokio::test]
-                async fn [<test_capability_ $cap>]() {
-                    let res_builder = |$arg: Operator| async move {
-                        let res = { $($body)* };
-                        res.await.err()
-                    };
-
-                    let builder = 
MockBuilder::default().with_capacity(Capability {
-                        $cap: false,
-                        ..Default::default()
-                    });
-                    let op = Operator::new(builder).expect("should 
build").finish();
-                    let res = res_builder(op.clone()).await;
-                    assert_eq!(res.expect("should not be None").kind(), 
ErrorKind::Unsupported);
-
-                    let builder = 
MockBuilder::default().with_capacity(Capability {
-                        $cap: true,
-                        ..Default::default()
-                    });
-                    let op = Operator::new(builder).expect("should 
build").finish();
-                    let res = res_builder(op.clone()).await;
-                    assert!(res.is_none());
-                }
-            }
-        };
+    fn new_test_operator(capability: Capability) -> Operator {
+        let srv = MockService { capability };
+
+        Operator::from_inner(Arc::new(srv)).layer(CompleteLayer)
+    }
+
+    #[tokio::test]
+    async fn test_read() {
+        let op = new_test_operator(Capability::default());
+        let res = op.read("path").await;
+        assert!(res.is_err());
+        assert_eq!(res.unwrap_err().kind(), ErrorKind::Unsupported);
+
+        let op = new_test_operator(Capability {
+            read: true,
+            ..Default::default()
+        });
+        let res = op.read("path").await;
+        assert!(res.is_ok())
+    }
+
+    #[tokio::test]
+    async fn test_stat() {
+        let op = new_test_operator(Capability::default());
+        let res = op.stat("path").await;
+        assert!(res.is_err());
+        assert_eq!(res.unwrap_err().kind(), ErrorKind::Unsupported);
+
+        let op = new_test_operator(Capability {
+            stat: true,
+            ..Default::default()
+        });
+        let res = op.stat("path").await;
+        assert!(res.is_ok())
     }
 
-    capability_test!(stat, |op| { op.stat("/path/to/mock_file") });
-    capability_test!(read, |op| { op.read("/path/to/mock_file") });
-    capability_test!(write, |op| { op.writer("/path/to/mock_file") });
-    capability_test!(create_dir, |op| { op.create_dir("/path/to/mock_dir/") });
-    capability_test!(delete, |op| { op.delete("/path/to/mock_file") });
-    capability_test!(copy, |op| {
-        op.copy("/path/to/mock_file", "/path/to/mock_file_2")
-    });
-    capability_test!(rename, |op| {
-        op.rename("/path/to/mock_file", "/path/to/mock_file_2")
-    });
-    capability_test!(list, |op| { op.lister("/path/to/mock_dir/") });
-    capability_test!(presign, |op| {
-        op.presign_read("/path/to/mock_file", Duration::from_secs(1))
-    });
+    #[tokio::test]
+    async fn test_writer() {
+        let op = new_test_operator(Capability::default());
+        let res = op.write("path", vec![]).await;
+        assert!(res.is_err());
+        assert_eq!(res.unwrap_err().kind(), ErrorKind::Unsupported);
+
+        let op = new_test_operator(Capability {
+            write: true,
+            ..Default::default()
+        });
+        let res = op.writer("path").await;
+        assert!(res.is_ok())
+    }
+
+    #[tokio::test]
+    async fn test_create_dir() {
+        let op = new_test_operator(Capability::default());
+        let res = op.create_dir("path/").await;
+        assert!(res.is_err());
+        assert_eq!(res.unwrap_err().kind(), ErrorKind::Unsupported);
+
+        let op = new_test_operator(Capability {
+            create_dir: true,
+            ..Default::default()
+        });
+        let res = op.create_dir("path/").await;
+        assert!(res.is_ok())
+    }
+
+    #[tokio::test]
+    async fn test_delete() {
+        let op = new_test_operator(Capability::default());
+        let res = op.delete("path").await;
+        assert!(res.is_err());
+        assert_eq!(res.unwrap_err().kind(), ErrorKind::Unsupported);
+
+        let op = new_test_operator(Capability {
+            delete: true,
+            ..Default::default()
+        });
+        let res = op.delete("path").await;
+        assert!(res.is_ok())
+    }
+
+    #[tokio::test]
+    async fn test_copy() {
+        let op = new_test_operator(Capability::default());
+        let res = op.copy("path_a", "path_b").await;
+        assert!(res.is_err());
+        assert_eq!(res.unwrap_err().kind(), ErrorKind::Unsupported);
+
+        let op = new_test_operator(Capability {
+            copy: true,
+            ..Default::default()
+        });
+        let res = op.copy("path_a", "path_b").await;
+        assert!(res.is_ok())
+    }
+
+    #[tokio::test]
+    async fn test_rename() {
+        let op = new_test_operator(Capability::default());
+        let res = op.rename("path_a", "path_b").await;
+        assert!(res.is_err());
+        assert_eq!(res.unwrap_err().kind(), ErrorKind::Unsupported);
+
+        let op = new_test_operator(Capability {
+            rename: true,
+            ..Default::default()
+        });
+        let res = op.rename("path_a", "path_b").await;
+        assert!(res.is_ok())
+    }
+
+    #[tokio::test]
+    async fn test_list() {
+        let op = new_test_operator(Capability::default());
+        let res = op.list("path/").await;
+        assert!(res.is_err());
+        assert_eq!(res.unwrap_err().kind(), ErrorKind::Unsupported);
+
+        let op = new_test_operator(Capability {
+            list: true,
+            ..Default::default()
+        });
+        let res = op.list("path/").await;
+        assert!(res.is_ok())
+    }
+
+    #[tokio::test]
+    async fn test_presign() {
+        let op = new_test_operator(Capability::default());
+        let res = op.presign_read("path", Duration::from_secs(1)).await;
+        assert!(res.is_err());
+        assert_eq!(res.unwrap_err().kind(), ErrorKind::Unsupported);
+
+        let op = new_test_operator(Capability {
+            presign: true,
+            ..Default::default()
+        });
+        let res = op.presign_read("path", Duration::from_secs(1)).await;
+        assert!(res.is_ok())
+    }
 }
diff --git a/core/src/raw/oio/page/api.rs b/core/src/raw/oio/page/api.rs
index 18bbe4c5d..62a265404 100644
--- a/core/src/raw/oio/page/api.rs
+++ b/core/src/raw/oio/page/api.rs
@@ -72,9 +72,9 @@ pub trait Page: Send + Sync + 'static {
 pub type Pager = Box<dyn Page>;
 
 #[async_trait]
-impl Page for Pager {
+impl<P: Page + ?Sized> Page for Box<P> {
     async fn next(&mut self) -> Result<Option<Vec<Entry>>> {
-        self.as_mut().next().await
+        (**self).next().await
     }
 }
 
@@ -107,9 +107,9 @@ pub trait BlockingPage: Send + 'static {
 /// BlockingPager is a boxed [`BlockingPage`]
 pub type BlockingPager = Box<dyn BlockingPage>;
 
-impl BlockingPage for BlockingPager {
+impl<P: BlockingPage + ?Sized> BlockingPage for Box<P> {
     fn next(&mut self) -> Result<Option<Vec<Entry>>> {
-        self.as_mut().next()
+        (**self).next()
     }
 }
 
@@ -119,7 +119,6 @@ impl BlockingPage for () {
     }
 }
 
-#[async_trait]
 impl<P: BlockingPage> BlockingPage for Option<P> {
     fn next(&mut self) -> Result<Option<Vec<Entry>>> {
         match self {

Reply via email to