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

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


The following commit(s) were added to refs/heads/main by this push:
     new f76b33cb docs(refactor): Add more detailed description of operator, 
accessor, and builder (#2094)
f76b33cb is described below

commit f76b33cb8275f891938a49ce918789d20efcd9f8
Author: Yansongsongsong <[email protected]>
AuthorDate: Mon Apr 24 23:00:10 2023 +0800

    docs(refactor): Add more detailed description of operator, accessor, and 
builder (#2094)
    
    * docs: fix some typos
    
    * docs: fix typo
    
    * docs: add more descriptions for builder API
    
    * docs: fix commet typo of memory builder
    
    * docs: fix typo of Accessor
    
    * docs: refactor operator accessor and builder related doc
    
    * fix: revert wrong fix
    
    * docs: fix incorrect description
    
    * docs: fix diagram representation
    
    * docs: fix unproper description of builder
    
    * docs: fix unproper decription of builder
    
    * docs: remove inappropriate analogy
---
 core/src/docs/concepts.rs           | 33 ++++++++++++++++++++++-----------
 core/src/docs/internals/accessor.rs |  2 +-
 core/src/raw/accessor.rs            | 13 +++++++++++--
 core/src/raw/adapters/kv/backend.rs |  8 +++++++-
 core/src/services/memory/backend.rs |  2 +-
 core/src/types/builder.rs           | 20 ++++++++++++++++----
 core/src/types/operator/operator.rs |  8 +++++++-
 7 files changed, 65 insertions(+), 21 deletions(-)

diff --git a/core/src/docs/concepts.rs b/core/src/docs/concepts.rs
index aa01e6e9..db4f06db 100644
--- a/core/src/docs/concepts.rs
+++ b/core/src/docs/concepts.rs
@@ -17,12 +17,15 @@
 
 //! The core concepts of OpenDAL's public API.
 //!
-//! OpenDAL provides a unified abstraction for all storage services.
+//! OpenDAL provides a unified abstraction that helps developers access all 
storage services.
 //!
 //! There are two core concepts in OpenDAL:
 //!
-//! - [`Builder`]: Build an instance of underlying services.
-//! - [`Operator`]: A bridge between underlying implementation detail and 
unified abstraction.
+//! - [`Builder`]: Builder accepts a series of parameters to set up an 
instance of underlying services.
+//! You can adjust the behaviour of underlying services with these parameters.
+//! - [`Operator`]: Developer can access underlying storage services with 
manipulating one Operator.
+//! The Operator is a delegate for underlying implementation detail, and 
provides one unified access interface,
+//! including `read`, `write`, `list` and so on.
 //!
 //! If you are interested in internal implementation details, please have a 
look at [`internals`][super::internals].
 //!
@@ -30,7 +33,9 @@
 //!
 //! Let's start with [`Builder`].
 //!
-//! A `Builder` is a trait that is implemented by the underlying services. We 
can use a `Builder` to configure and create a service. Builder is the only 
public API provided by services, and the detailed implementation is hidden.
+//! A `Builder` is a trait that is implemented by the underlying services. We 
can use a `Builder` to configure and create a service.
+//! Developer can only create one service via Builder, in other words, Builder 
is the only public API provided by services.
+//! And other detailed implementation will be hidden.
 //!
 //! ```text
 //! ┌───────────┐                 ┌───────────┐
@@ -41,6 +46,8 @@
 //! ```
 //!
 //! All [`Builder`] provided by OpenDAL is under 
[`services`][crate::services], we can refer to them like 
`opendal::services::S3`.
+//! By right the builder will be named like `OneServiceBuilder`, but usually 
we will export it to public with renaming it as one
+//! general name. For example, we will rename `S3Builder` to `S3` and 
developer will use `S3` finally.
 //!
 //! For example:
 //!
@@ -53,15 +60,19 @@
 //! ```
 //!
 //! # Operator
-//!
-//! The [`Operator`] is a bridge between the underlying implementation details 
and the unified abstraction. OpenDAL will erase all generic types and higher 
abstraction around it.
+//! The [`Operator`] is a delegate for Service, the underlying implementation 
detail that implements [`Accessor`][crate::raw::Accessor],
+//! and it also provides one unified access interface.
+//! It will hold one reference of Service with its all generic types erased by 
OpenDAL,
+//! which is the reason why we say the Operator is the delegate of one Service.
 //!
 //! ```text
-//! ┌───────────┐           ┌───────────┐              ┌─────────────────┐
-//! │           │  build()  │           │  type erase  │                 │
-//! │  Builder  ├──────────►│  Service  ├─────────────►│     Operator    │
-//! │           │           │           │              │                 │
-//! └───────────┘           └───────────┘              └─────────────────┘
+//!                   ┌────────────────────┐
+//!                   │      Operator      │
+//!                   │         │delegate  │
+//! ┌─────────┐ build │         ▼          │ rely on ┌─────────────────────┐
+//! │ Builder ├───────┼──►┌────────────┐   │◄────────┤ business logic code │
+//! └─────────┘       │   │  Service   │   │         └─────────────────────┘
+//!                   └───┴────────────┴───┘
 //! ```
 //!
 //! `Operator` can be built from `Builder`:
diff --git a/core/src/docs/internals/accessor.rs 
b/core/src/docs/internals/accessor.rs
index 463ac5c8..d149457e 100644
--- a/core/src/docs/internals/accessor.rs
+++ b/core/src/docs/internals/accessor.rs
@@ -148,7 +148,7 @@
 //!
 //! First of all, let's pick a good [`Scheme`] for our duck service. The
 //! scheme should be unique and easy to understand. Normally we should
-//! use it's formal name.
+//! use its formal name.
 //!
 //! For example, we will use `s3` for AWS S3 Compatible Storage Service
 //! instead of `aws` or `awss3`. This is because there are many storage
diff --git a/core/src/raw/accessor.rs b/core/src/raw/accessor.rs
index d551fda0..ee6e7618 100644
--- a/core/src/raw/accessor.rs
+++ b/core/src/raw/accessor.rs
@@ -26,6 +26,16 @@ use crate::*;
 
 /// Underlying trait of all backends for implementors.
 ///
+/// The actual data access of storage service happens in Accessor layer.
+/// Every storage supported by OpenDAL must implement [`Accessor`] but not all
+/// methods of [`Accessor`] will be implemented according to how the storage 
service is.
+///
+/// For example, user can not modify the content from one HTTP file server 
directly.
+/// So [`Http`][crate::services::Http] implements and provides only read 
related actions.
+///
+/// [`Accessor`] gives default implementation for all methods which will raise 
[`ErrorKind::Unsupported`] error.
+/// And what action this [`Accessor`] supports will be pointed out in 
[`AccessorInfo`].
+///
 /// # Note
 ///
 /// Visit [`internals`][crate::docs::internals] for more tutorials.
@@ -73,7 +83,6 @@ pub trait Accessor: Send + Sync + Debug + Unpin + 'static {
     ///
     /// - scheme: declare the scheme of backend.
     /// - capabilities: declare the capabilities of current backend.
-    /// - hints: declare the hints of current backend
     fn info(&self) -> AccessorInfo;
 
     /// Invoke the `create` operation on the specified path
@@ -487,7 +496,7 @@ impl<T: Accessor + ?Sized> Accessor for Arc<T> {
     }
 }
 
-/// FusedAccessor is the type erased accessor with `Box<dyn Read>`.
+/// FusedAccessor is the type erased accessor with `Arc<dyn Accessor>`.
 pub type FusedAccessor = Arc<
     dyn Accessor<
         Reader = oio::Reader,
diff --git a/core/src/raw/adapters/kv/backend.rs 
b/core/src/raw/adapters/kv/backend.rs
index 855b9475..55273102 100644
--- a/core/src/raw/adapters/kv/backend.rs
+++ b/core/src/raw/adapters/kv/backend.rs
@@ -25,7 +25,13 @@ use crate::ops::*;
 use crate::raw::*;
 use crate::*;
 
-/// Backend of kv service.
+/// Backend of kv service. If the storage service is one k-v-like service, it 
should implement this kv [`Backend`] by right.
+///
+/// `Backend` implements one general logic on how to read, write, scan the 
data from one kv store efficiently.
+/// And the [`Adapter`] held by `Backend` will handle how to communicate with 
one k-v-like service really and provides
+/// a series of basic operation for this service.
+///
+/// OpenDAL developer can implement one new k-v store backend easily with help 
of this Backend.
 #[derive(Debug, Clone)]
 pub struct Backend<S: Adapter> {
     kv: Arc<S>,
diff --git a/core/src/services/memory/backend.rs 
b/core/src/services/memory/backend.rs
index f34b2b0d..34c77350 100644
--- a/core/src/services/memory/backend.rs
+++ b/core/src/services/memory/backend.rs
@@ -43,7 +43,7 @@ pub struct MemoryBuilder {
 }
 
 impl MemoryBuilder {
-    /// Set the root for dashmap.
+    /// Set the root for BTreeMap.
     pub fn root(&mut self, path: &str) -> &mut Self {
         self.root = Some(path.into());
         self
diff --git a/core/src/types/builder.rs b/core/src/types/builder.rs
index 252ce9cc..237c103c 100644
--- a/core/src/types/builder.rs
+++ b/core/src/types/builder.rs
@@ -21,16 +21,28 @@ use std::env;
 use crate::raw::*;
 use crate::*;
 
-/// Builder is used to build a storage accessor used by [`Operator`].
+/// Builder is used to set up a real underlying service, i.e. storage accessor.
+///
+/// One builder is usually used by [`Operator`] during its initialization.
+/// It can be created by accepting several k-v pairs from one HashMap, one 
iterator and specific environment variables.
+///
+/// By default each builder of underlying service must support deriving from 
one HashMap.
+/// Besides that, according to the implementation, each builder will have its 
own special methods
+/// to control the behavior of initialization of the underlying service.
+/// It often provides semantic interface instead of using dynamic k-v strings 
directly.
+/// Because the latter way is obscure and hard to remember how many parameters 
it will have.
+///
+/// So it is recommended that developer should read related doc of builder 
carefully when you are working with one service.
+/// We also promise that every public API will provide detailed documentation.
 ///
 /// It's recommended to use [`Operator::new`] to avoid use `Builder` trait 
directly.
 pub trait Builder: Default {
-    /// Associated scheme for this builder.
+    /// Associated scheme for this builder. It indicates what underlying 
service is.
     const SCHEME: Scheme;
     /// The accessor that built by this builder.
     type Accessor: Accessor;
 
-    /// Construct a builder from given map.
+    /// Construct a builder from given map which contains several parameters 
needed by underlying service.
     fn from_map(map: HashMap<String, String>) -> Self;
 
     /// Construct a builder from given iterator.
@@ -41,7 +53,7 @@ pub trait Builder: Default {
         Self::from_map(iter.collect())
     }
 
-    /// Construct a builder from envs.
+    /// Construct a builder from envs. Please note that the env should begin 
with `opendal_{schema_name}_`.
     fn from_env() -> Self
     where
         Self: Sized,
diff --git a/core/src/types/operator/operator.rs 
b/core/src/types/operator/operator.rs
index 8187bdb1..8fdd9bf7 100644
--- a/core/src/types/operator/operator.rs
+++ b/core/src/types/operator/operator.rs
@@ -33,7 +33,10 @@ use crate::raw::*;
 use crate::*;
 
 /// Operator is the entry for all public async APIs.
+/// Developer should manipulate the data from storage service through Operator 
only by right.
 ///
+/// We will usually do some general checks and data transformations in this 
layer,
+/// like normalizing path from input, checking whether the path refers to one 
file or one directory, and so on.
 /// Read [`concepts`][docs::concepts] for know more about [`Operator`].
 ///
 /// # Examples
@@ -61,8 +64,10 @@ use crate::*;
 /// ```
 #[derive(Clone, Debug)]
 pub struct Operator {
+    // accessor is what Operator delegates for
     accessor: FusedAccessor,
 
+    // limit is usually the maximum size of data that operator will handle in 
one operation
     limit: usize,
 }
 
@@ -85,7 +90,8 @@ impl Operator {
         self.accessor
     }
 
-    /// Get current operator's limit
+    /// Get current operator's limit.
+    /// Limit is usually the maximum size of data that operator will handle in 
one operation.
     pub fn limit(&self) -> usize {
         self.limit
     }

Reply via email to