You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2025/07/31 10:21:40 UTC

(opendal) 01/03: Don't use scheme inside raw

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

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

commit 889bbdc053987bc45c7a038c287fcf9a27f98ff3
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Thu Jul 31 17:28:07 2025 +0800

    Don't use scheme inside raw
    
    Signed-off-by: Xuanwo <gi...@xuanwo.io>
---
 core/src/docs/internals/accessor.rs           |  3 +-
 core/src/layers/error_context.rs              |  4 +-
 core/src/layers/fastmetrics.rs                |  2 +-
 core/src/layers/metrics.rs                    |  2 +-
 core/src/layers/observe/metrics.rs            |  2 +-
 core/src/layers/otelmetrics.rs                |  2 +-
 core/src/layers/prometheus.rs                 |  2 +-
 core/src/layers/prometheus_client.rs          |  2 +-
 core/src/layers/retry.rs                      | 24 ++++----
 core/src/raw/accessor.rs                      | 28 +++++++---
 core/src/raw/adapters/kv/backend.rs           |  2 +-
 core/src/raw/adapters/typed_kv/backend.rs     |  2 +-
 core/src/raw/azure.rs                         | 80 +++++++++++++++++----------
 core/src/raw/layer.rs                         |  2 +-
 core/src/services/aliyun_drive/backend.rs     |  3 +-
 core/src/services/alluxio/backend.rs          |  3 +-
 core/src/services/azblob/backend.rs           |  3 +-
 core/src/services/azdls/backend.rs            |  3 +-
 core/src/services/azfile/backend.rs           |  3 +-
 core/src/services/b2/backend.rs               |  3 +-
 core/src/services/cacache/backend.rs          |  3 +-
 core/src/services/cloudflare_kv/backend.rs    |  1 -
 core/src/services/compfs/backend.rs           |  3 +-
 core/src/services/cos/backend.rs              |  3 +-
 core/src/services/d1/backend.rs               |  1 -
 core/src/services/dashmap/backend.rs          |  3 +-
 core/src/services/dbfs/backend.rs             |  3 +-
 core/src/services/dropbox/builder.rs          |  3 +-
 core/src/services/etcd/backend.rs             |  1 -
 core/src/services/foundationdb/backend.rs     |  1 -
 core/src/services/fs/backend.rs               |  3 +-
 core/src/services/ftp/backend.rs              |  3 +-
 core/src/services/gcs/backend.rs              |  3 +-
 core/src/services/gdrive/builder.rs           |  3 +-
 core/src/services/ghac/backend.rs             |  3 +-
 core/src/services/ghac/writer.rs              |  2 +-
 core/src/services/github/backend.rs           |  3 +-
 core/src/services/gridfs/backend.rs           |  1 -
 core/src/services/hdfs/backend.rs             |  3 +-
 core/src/services/hdfs_native/backend.rs      |  3 +-
 core/src/services/http/backend.rs             |  3 +-
 core/src/services/huggingface/backend.rs      |  3 +-
 core/src/services/ipfs/backend.rs             |  3 +-
 core/src/services/ipmfs/builder.rs            |  3 +-
 core/src/services/koofr/backend.rs            |  3 +-
 core/src/services/lakefs/backend.rs           | 26 ++++-----
 core/src/services/memcached/backend.rs        |  1 -
 core/src/services/memory/backend.rs           |  3 +-
 core/src/services/mini_moka/backend.rs        |  3 +-
 core/src/services/moka/backend.rs             |  3 +-
 core/src/services/mongodb/backend.rs          |  1 -
 core/src/services/monoiofs/backend.rs         |  1 -
 core/src/services/monoiofs/core.rs            |  2 +-
 core/src/services/mysql/backend.rs            |  1 -
 core/src/services/obs/backend.rs              |  3 +-
 core/src/services/onedrive/builder.rs         |  3 +-
 core/src/services/oss/backend.rs              |  3 +-
 core/src/services/pcloud/backend.rs           |  3 +-
 core/src/services/persy/backend.rs            |  1 -
 core/src/services/postgresql/backend.rs       |  1 -
 core/src/services/redb/backend.rs             |  1 -
 core/src/services/redis/backend.rs            |  5 +-
 core/src/services/rocksdb/backend.rs          |  1 -
 core/src/services/s3/backend.rs               |  3 +-
 core/src/services/seafile/backend.rs          |  3 +-
 core/src/services/sftp/backend.rs             |  3 +-
 core/src/services/sled/backend.rs             |  1 -
 core/src/services/sqlite/backend.rs           |  1 -
 core/src/services/surrealdb/backend.rs        |  1 -
 core/src/services/swift/backend.rs            |  3 +-
 core/src/services/tikv/backend.rs             |  1 -
 core/src/services/upyun/backend.rs            |  3 +-
 core/src/services/vercel_artifacts/builder.rs |  4 +-
 core/src/services/vercel_blob/backend.rs      |  3 +-
 core/src/services/webdav/backend.rs           |  3 +-
 core/src/services/webhdfs/backend.rs          |  3 +-
 core/src/services/yandex_disk/backend.rs      |  3 +-
 core/src/types/builder.rs                     |  3 -
 core/src/types/operator/info.rs               |  4 +-
 core/src/types/operator/operator.rs           |  2 +-
 80 files changed, 158 insertions(+), 187 deletions(-)

diff --git a/core/src/docs/internals/accessor.rs b/core/src/docs/internals/accessor.rs
index 30c6c6293..7e629d367 100644
--- a/core/src/docs/internals/accessor.rs
+++ b/core/src/docs/internals/accessor.rs
@@ -251,7 +251,6 @@
 //! }
 //!
 //! impl Builder for DuckBuilder {
-//!     const SCHEME: Scheme = Scheme::Duck;
 //!     type Accessor = DuckBackend;
 //!     type Config = DuckConfig;
 //!
@@ -298,7 +297,7 @@
 //!
 //!     fn metadata(&self) -> AccessorInfo {
 //!         let am = AccessorInfo::default();
-//!         am.set_scheme(Scheme::Duck)
+//!         am.set_scheme("duck")
 //!             .set_root(&self.root)
 //!             .set_capability(
 //!                 Capability {
diff --git a/core/src/layers/error_context.rs b/core/src/layers/error_context.rs
index f82a75152..315068a98 100644
--- a/core/src/layers/error_context.rs
+++ b/core/src/layers/error_context.rs
@@ -188,7 +188,7 @@ impl<A: Access> LayeredAccess for ErrorContextAccessor<A> {
 }
 
 pub struct ErrorContextWrapper<T> {
-    scheme: Scheme,
+    scheme: &'static str,
     path: String,
     inner: T,
     range: BytesRange,
@@ -196,7 +196,7 @@ pub struct ErrorContextWrapper<T> {
 }
 
 impl<T> ErrorContextWrapper<T> {
-    fn new(scheme: Scheme, path: String, inner: T) -> Self {
+    fn new(scheme: &'static str, path: String, inner: T) -> Self {
         Self {
             scheme,
             path,
diff --git a/core/src/layers/fastmetrics.rs b/core/src/layers/fastmetrics.rs
index 2ce066fe3..8ee44fc8d 100644
--- a/core/src/layers/fastmetrics.rs
+++ b/core/src/layers/fastmetrics.rs
@@ -508,7 +508,7 @@ struct OperationLabels {
 
 impl EncodeLabelSet for OperationLabels {
     fn encode(&self, encoder: &mut dyn LabelSetEncoder) -> fmt::Result {
-        encoder.encode(&(observe::LABEL_SCHEME, self.labels.scheme.into_static()))?;
+        encoder.encode(&(observe::LABEL_SCHEME, self.labels.scheme))?;
         encoder.encode(&(observe::LABEL_NAMESPACE, self.labels.namespace.as_ref()))?;
         if !self.disable_label_root {
             encoder.encode(&(observe::LABEL_ROOT, self.labels.root.as_ref()))?;
diff --git a/core/src/layers/metrics.rs b/core/src/layers/metrics.rs
index 90717bc90..cf3591c52 100644
--- a/core/src/layers/metrics.rs
+++ b/core/src/layers/metrics.rs
@@ -160,7 +160,7 @@ impl OperationLabels {
         let mut labels = Vec::with_capacity(6);
 
         labels.extend([
-            Label::new(observe::LABEL_SCHEME, self.0.scheme.into_static()),
+            Label::new(observe::LABEL_SCHEME, self.0.scheme),
             Label::new(observe::LABEL_NAMESPACE, self.0.namespace),
             Label::new(observe::LABEL_ROOT, self.0.root),
             Label::new(observe::LABEL_OPERATION, self.0.operation),
diff --git a/core/src/layers/observe/metrics.rs b/core/src/layers/observe/metrics.rs
index 20290338d..7e90d3da3 100644
--- a/core/src/layers/observe/metrics.rs
+++ b/core/src/layers/observe/metrics.rs
@@ -151,7 +151,7 @@ pub static LABEL_STATUS_CODE: &str = "status_code";
 pub struct MetricLabels {
     /// The storage scheme identifier (e.g., "s3", "gcs", "azblob", "fs").
     /// Used to differentiate between different storage backends.
-    pub scheme: Scheme,
+    pub scheme: &'static str,
     /// The storage namespace (e.g., bucket name, container name).
     /// Identifies the specific storage container being accessed.
     pub namespace: Arc<str>,
diff --git a/core/src/layers/otelmetrics.rs b/core/src/layers/otelmetrics.rs
index 95c416faa..c25b8a633 100644
--- a/core/src/layers/otelmetrics.rs
+++ b/core/src/layers/otelmetrics.rs
@@ -432,7 +432,7 @@ impl OtelMetricsInterceptor {
         let mut attributes = Vec::with_capacity(6);
 
         attributes.extend([
-            KeyValue::new(observe::LABEL_SCHEME, attrs.scheme.into_static()),
+            KeyValue::new(observe::LABEL_SCHEME, attrs.scheme),
             KeyValue::new(observe::LABEL_NAMESPACE, attrs.namespace),
             KeyValue::new(observe::LABEL_ROOT, attrs.root),
             KeyValue::new(observe::LABEL_OPERATION, attrs.operation),
diff --git a/core/src/layers/prometheus.rs b/core/src/layers/prometheus.rs
index 7667f0604..ce7bc8455 100644
--- a/core/src/layers/prometheus.rs
+++ b/core/src/layers/prometheus.rs
@@ -667,7 +667,7 @@ impl OperationLabels {
         let mut labels = Vec::with_capacity(6);
 
         labels.extend([
-            self.0.scheme.into_static(),
+            self.0.scheme,
             self.0.namespace.as_ref(),
             self.0.root.as_ref(),
             self.0.operation,
diff --git a/core/src/layers/prometheus_client.rs b/core/src/layers/prometheus_client.rs
index f6836f00e..827b7dd0d 100644
--- a/core/src/layers/prometheus_client.rs
+++ b/core/src/layers/prometheus_client.rs
@@ -490,7 +490,7 @@ struct OperationLabels {
 
 impl EncodeLabelSet for OperationLabels {
     fn encode(&self, mut encoder: LabelSetEncoder) -> Result<(), fmt::Error> {
-        (observe::LABEL_SCHEME, self.labels.scheme.into_static()).encode(encoder.encode_label())?;
+        (observe::LABEL_SCHEME, self.labels.scheme).encode(encoder.encode_label())?;
         (observe::LABEL_NAMESPACE, self.labels.namespace.as_ref())
             .encode(encoder.encode_label())?;
         if !self.disable_label_root {
diff --git a/core/src/layers/retry.rs b/core/src/layers/retry.rs
index 19471f732..3e4ab754c 100644
--- a/core/src/layers/retry.rs
+++ b/core/src/layers/retry.rs
@@ -619,7 +619,6 @@ mod tests {
     }
 
     impl Builder for MockBuilder {
-        const SCHEME: Scheme = Scheme::Custom("mock");
         type Config = ();
 
         fn build(self) -> Result<impl Access> {
@@ -642,18 +641,17 @@ mod tests {
 
         fn info(&self) -> Arc<AccessorInfo> {
             let am = AccessorInfo::default();
-            am.set_scheme(Scheme::Custom("mock"))
-                .set_native_capability(Capability {
-                    read: true,
-                    write: true,
-                    write_can_multi: true,
-                    delete: true,
-                    delete_max_size: Some(10),
-                    stat: true,
-                    list: true,
-                    list_with_recursive: true,
-                    ..Default::default()
-                });
+            am.set_scheme("mock").set_native_capability(Capability {
+                read: true,
+                write: true,
+                write_can_multi: true,
+                delete: true,
+                delete_max_size: Some(10),
+                stat: true,
+                list: true,
+                list_with_recursive: true,
+                ..Default::default()
+            });
 
             am.into()
         }
diff --git a/core/src/raw/accessor.rs b/core/src/raw/accessor.rs
index 821c0d32b..8a8157211 100644
--- a/core/src/raw/accessor.rs
+++ b/core/src/raw/accessor.rs
@@ -450,7 +450,7 @@ impl Access for () {
 
     fn info(&self) -> Arc<AccessorInfo> {
         let ai = AccessorInfo::default();
-        ai.set_scheme(Scheme::Custom("dummy"))
+        ai.set_scheme("dummy")
             .set_root("")
             .set_name("dummy")
             .set_native_capability(Capability::default());
@@ -543,9 +543,9 @@ impl<T: Access + ?Sized> Access for Arc<T> {
 /// Accessor is the type erased accessor with `Arc<dyn Accessor>`.
 pub type Accessor = Arc<dyn AccessDyn>;
 
-#[derive(Debug, Default)]
+#[derive(Debug)]
 struct AccessorInfoInner {
-    scheme: Scheme,
+    scheme: &'static str,
     root: Arc<str>,
     name: Arc<str>,
 
@@ -556,6 +556,20 @@ struct AccessorInfoInner {
     executor: Executor,
 }
 
+impl Default for AccessorInfoInner {
+    fn default() -> Self {
+        Self {
+            scheme: "unknown",
+            root: Arc::from(""),
+            name: Arc::from(""),
+            native_capability: Capability::default(),
+            full_capability: Capability::default(),
+            http_client: HttpClient::default(),
+            executor: Executor::default(),
+        }
+    }
+}
+
 /// Info for the accessor. Users can use this struct to retrieve information about the underlying backend.
 ///
 /// This struct is intentionally not implemented with `Clone` to ensure that all accesses
@@ -621,27 +635,27 @@ impl Hash for AccessorInfo {
 }
 
 impl AccessorInfo {
-    /// [`Scheme`] of backend.
+    /// Scheme of backend.
     ///
     /// # Panic Safety
     ///
     /// This method safely handles lock poisoning scenarios. If the inner `RwLock` is poisoned,
     /// this method will gracefully continue execution by simply returning the current scheme.
-    pub fn scheme(&self) -> Scheme {
+    pub fn scheme(&self) -> &'static str {
         match self.inner.read() {
             Ok(v) => v.scheme,
             Err(err) => err.get_ref().scheme,
         }
     }
 
-    /// Set [`Scheme`] for backend.
+    /// Set scheme for backend.
     ///
     /// # Panic Safety
     ///
     /// This method safely handles lock poisoning scenarios. If the inner `RwLock` is poisoned,
     /// this method will gracefully continue execution by simply skipping the update operation
     /// rather than propagating the panic.
-    pub fn set_scheme(&self, scheme: Scheme) -> &Self {
+    pub fn set_scheme(&self, scheme: &'static str) -> &Self {
         if let Ok(mut v) = self.inner.write() {
             v.scheme = scheme;
         }
diff --git a/core/src/raw/adapters/kv/backend.rs b/core/src/raw/adapters/kv/backend.rs
index 05bb716b1..dde5b1c50 100644
--- a/core/src/raw/adapters/kv/backend.rs
+++ b/core/src/raw/adapters/kv/backend.rs
@@ -51,7 +51,7 @@ where
             info: {
                 let am: AccessorInfo = AccessorInfo::default();
                 am.set_root("/");
-                am.set_scheme(kv_info.scheme());
+                am.set_scheme(kv_info.scheme().into_static());
                 am.set_name(kv_info.name());
 
                 let mut cap = kv_info.capabilities();
diff --git a/core/src/raw/adapters/typed_kv/backend.rs b/core/src/raw/adapters/typed_kv/backend.rs
index 8e08438b0..70aabdbe7 100644
--- a/core/src/raw/adapters/typed_kv/backend.rs
+++ b/core/src/raw/adapters/typed_kv/backend.rs
@@ -46,7 +46,7 @@ where
             info: {
                 let am: AccessorInfo = AccessorInfo::default();
                 am.set_root("/");
-                am.set_scheme(kv_info.scheme());
+                am.set_scheme(kv_info.scheme().into_static());
                 am.set_name(kv_info.name());
 
                 let kv_cap = kv_info.capabilities();
diff --git a/core/src/raw/azure.rs b/core/src/raw/azure.rs
index bfa58ee00..70c6f7fcc 100644
--- a/core/src/raw/azure.rs
+++ b/core/src/raw/azure.rs
@@ -75,10 +75,12 @@ pub(crate) enum AzureStorageService {
     Blob,
 
     /// Azure File Storage.
+    #[cfg(feature = "services-azfile")]
     File,
 
     /// Azure Data Lake Storage Gen2.
     /// Backed by Blob Storage but exposed through a different endpoint (`dfs`).
+    #[cfg(feature = "services-azdls")]
     Adls,
 }
 
@@ -180,7 +182,9 @@ fn collect_endpoint(
 ) -> Result<Option<String>> {
     match storage {
         AzureStorageService::Blob => collect_or_build_endpoint(key_values, "BlobEndpoint", "blob"),
+        #[cfg(feature = "services-azfile")]
         AzureStorageService::File => collect_or_build_endpoint(key_values, "FileEndpoint", "file"),
+        #[cfg(feature = "services-azdls")]
         AzureStorageService::Adls => {
             // ADLS doesn't have a dedicated endpoint field and we can only
             // build it from parts.
@@ -281,7 +285,8 @@ mod tests {
 
     #[test]
     fn test_azure_config_from_connection_string() {
-        let test_cases = vec![
+        #[allow(unused_mut)]
+        let mut test_cases = vec![
             ("minimal fields",
                 (AzureStorageService::Blob, "BlobEndpoint=https://testaccount.blob.core.windows.net/"),
                 Some(AzureStorageConfig{
@@ -322,29 +327,6 @@ mod tests {
                     ..Default::default()
                 }),
             ),
-            ("adls endpoint from parts",
-                (AzureStorageService::Adls, "AccountName=testaccount;EndpointSuffix=core.windows.net;DefaultEndpointsProtocol=https"),
-                Some(AzureStorageConfig{
-                    account_name: Some("testaccount".to_string()),
-                    endpoint: Some("https://testaccount.dfs.core.windows.net".to_string()),
-                    ..Default::default()
-                }),
-            ),
-            ("file endpoint from field",
-                (AzureStorageService::File, "FileEndpoint=https://testaccount.file.core.windows.net"),
-                Some(AzureStorageConfig{
-                    endpoint: Some("https://testaccount.file.core.windows.net".to_string()),
-                    ..Default::default()
-                })
-            ),
-            ("file endpoint from parts",
-                (AzureStorageService::File, "AccountName=testaccount;EndpointSuffix=core.windows.net"),
-                Some(AzureStorageConfig{
-                    account_name: Some("testaccount".to_string()),
-                    endpoint: Some("https://testaccount.file.core.windows.net".to_string()),
-                    ..Default::default()
-                }),
-            ),
             ("prefers sas over key",
                 (AzureStorageService::Blob, "AccountName=testaccount;AccountKey=testkey;SharedAccessSignature=sas_token"),
                 Some(AzureStorageConfig{
@@ -415,12 +397,54 @@ mod tests {
                 (AzureStorageService::Blob, "DefaultEndpointsProtocol=ftp;AccountName=example;EndpointSuffix=core.windows.net",),
                 None, // This should fail due to invalid protocol
             ),
-            ("azdls development storage",
-                (AzureStorageService::Adls, "UseDevelopmentStorage=true"),
-                Some(AzureStorageConfig::default()), // Azurite doesn't support ADLSv2, so we ignore this case
-            ),
         ];
 
+        #[cfg(feature = "services-azdls")]
+        test_cases.push(
+            ("adls endpoint from parts",
+                (AzureStorageService::Adls, "AccountName=testaccount;EndpointSuffix=core.windows.net;DefaultEndpointsProtocol=https"),
+                Some(AzureStorageConfig{
+                    account_name: Some("testaccount".to_string()),
+                    endpoint: Some("https://testaccount.dfs.core.windows.net".to_string()),
+                    ..Default::default()
+                }),
+            )
+        );
+
+        #[cfg(feature = "services-azfile")]
+        test_cases.extend(vec![
+            (
+                "file endpoint from field",
+                (
+                    AzureStorageService::File,
+                    "FileEndpoint=https://testaccount.file.core.windows.net",
+                ),
+                Some(AzureStorageConfig {
+                    endpoint: Some("https://testaccount.file.core.windows.net".to_string()),
+                    ..Default::default()
+                }),
+            ),
+            (
+                "file endpoint from parts",
+                (
+                    AzureStorageService::File,
+                    "AccountName=testaccount;EndpointSuffix=core.windows.net",
+                ),
+                Some(AzureStorageConfig {
+                    account_name: Some("testaccount".to_string()),
+                    endpoint: Some("https://testaccount.file.core.windows.net".to_string()),
+                    ..Default::default()
+                }),
+            ),
+        ]);
+
+        #[cfg(feature = "services-azdls")]
+        test_cases.push((
+            "azdls development storage",
+            (AzureStorageService::Adls, "UseDevelopmentStorage=true"),
+            Some(AzureStorageConfig::default()), // Azurite doesn't support ADLSv2, so we ignore this case
+        ));
+
         for (name, (storage, conn_str), expected) in test_cases {
             let actual = azure_config_from_connection_string(conn_str, storage);
 
diff --git a/core/src/raw/layer.rs b/core/src/raw/layer.rs
index 86151c4e0..2d34d4956 100644
--- a/core/src/raw/layer.rs
+++ b/core/src/raw/layer.rs
@@ -261,7 +261,7 @@ mod tests {
 
         fn info(&self) -> Arc<AccessorInfo> {
             let am = AccessorInfo::default();
-            am.set_scheme(Scheme::Custom("test"));
+            am.set_scheme("test");
             am.into()
         }
 
diff --git a/core/src/services/aliyun_drive/backend.rs b/core/src/services/aliyun_drive/backend.rs
index 2a1ca4893..929f076cc 100644
--- a/core/src/services/aliyun_drive/backend.rs
+++ b/core/src/services/aliyun_drive/backend.rs
@@ -130,7 +130,6 @@ impl AliyunDriveBuilder {
 }
 
 impl Builder for AliyunDriveBuilder {
-    const SCHEME: Scheme = Scheme::AliyunDrive;
     type Config = AliyunDriveConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -177,7 +176,7 @@ impl Builder for AliyunDriveBuilder {
             core: Arc::new(AliyunDriveCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::AliyunDrive)
+                    am.set_scheme("aliyun_drive")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/alluxio/backend.rs b/core/src/services/alluxio/backend.rs
index 01c04cb49..de61b1794 100644
--- a/core/src/services/alluxio/backend.rs
+++ b/core/src/services/alluxio/backend.rs
@@ -104,7 +104,6 @@ impl AlluxioBuilder {
 }
 
 impl Builder for AlluxioBuilder {
-    const SCHEME: Scheme = Scheme::Alluxio;
     type Config = AlluxioConfig;
 
     /// Builds the backend and returns the result of AlluxioBackend.
@@ -126,7 +125,7 @@ impl Builder for AlluxioBuilder {
             core: Arc::new(AlluxioCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Alluxio)
+                    am.set_scheme("alluxio")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/azblob/backend.rs b/core/src/services/azblob/backend.rs
index 4a1dfa270..bc1276ad7 100644
--- a/core/src/services/azblob/backend.rs
+++ b/core/src/services/azblob/backend.rs
@@ -301,7 +301,6 @@ impl AzblobBuilder {
 }
 
 impl Builder for AzblobBuilder {
-    const SCHEME: Scheme = Scheme::Azblob;
     type Config = AzblobConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -385,7 +384,7 @@ impl Builder for AzblobBuilder {
             core: Arc::new(AzblobCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Azblob)
+                    am.set_scheme("azblob")
                         .set_root(&root)
                         .set_name(container)
                         .set_native_capability(Capability {
diff --git a/core/src/services/azdls/backend.rs b/core/src/services/azdls/backend.rs
index e4916acf9..f311fe3c7 100644
--- a/core/src/services/azdls/backend.rs
+++ b/core/src/services/azdls/backend.rs
@@ -249,7 +249,6 @@ impl AzdlsBuilder {
 }
 
 impl Builder for AzdlsBuilder {
-    const SCHEME: Scheme = Scheme::Azdls;
     type Config = AzdlsConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -296,7 +295,7 @@ impl Builder for AzdlsBuilder {
             core: Arc::new(AzdlsCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Azdls)
+                    am.set_scheme("azdls")
                         .set_root(&root)
                         .set_name(filesystem)
                         .set_native_capability(Capability {
diff --git a/core/src/services/azfile/backend.rs b/core/src/services/azfile/backend.rs
index 725580a81..5ab99c7b9 100644
--- a/core/src/services/azfile/backend.rs
+++ b/core/src/services/azfile/backend.rs
@@ -181,7 +181,6 @@ impl AzfileBuilder {
 }
 
 impl Builder for AzfileBuilder {
-    const SCHEME: Scheme = Scheme::Azfile;
     type Config = AzfileConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -226,7 +225,7 @@ impl Builder for AzfileBuilder {
             core: Arc::new(AzfileCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Azfile)
+                    am.set_scheme("azfile")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/b2/backend.rs b/core/src/services/b2/backend.rs
index 064e8d15d..9c449e91c 100644
--- a/core/src/services/b2/backend.rs
+++ b/core/src/services/b2/backend.rs
@@ -136,7 +136,6 @@ impl B2Builder {
 }
 
 impl Builder for B2Builder {
-    const SCHEME: Scheme = Scheme::B2;
     type Config = B2Config;
 
     /// Builds the backend and returns the result of B2Backend.
@@ -192,7 +191,7 @@ impl Builder for B2Builder {
             core: Arc::new(B2Core {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::B2)
+                    am.set_scheme("b2")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/cacache/backend.rs b/core/src/services/cacache/backend.rs
index f48610e92..846b625cb 100644
--- a/core/src/services/cacache/backend.rs
+++ b/core/src/services/cacache/backend.rs
@@ -51,7 +51,6 @@ impl CacacheBuilder {
 }
 
 impl Builder for CacacheBuilder {
-    const SCHEME: Scheme = Scheme::Cacache;
     type Config = CacacheConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -65,7 +64,7 @@ impl Builder for CacacheBuilder {
         };
 
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Cacache);
+        info.set_scheme("cacache");
         info.set_name(&datadir_path);
         info.set_root("/");
         info.set_native_capability(Capability {
diff --git a/core/src/services/cloudflare_kv/backend.rs b/core/src/services/cloudflare_kv/backend.rs
index aa48cb66d..d2cbda4d0 100644
--- a/core/src/services/cloudflare_kv/backend.rs
+++ b/core/src/services/cloudflare_kv/backend.rs
@@ -96,7 +96,6 @@ impl CloudflareKvBuilder {
 }
 
 impl Builder for CloudflareKvBuilder {
-    const SCHEME: Scheme = Scheme::CloudflareKv;
     type Config = CloudflareKvConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/compfs/backend.rs b/core/src/services/compfs/backend.rs
index a93270e16..dcd005263 100644
--- a/core/src/services/compfs/backend.rs
+++ b/core/src/services/compfs/backend.rs
@@ -58,7 +58,6 @@ impl CompfsBuilder {
 }
 
 impl Builder for CompfsBuilder {
-    const SCHEME: Scheme = Scheme::Compfs;
     type Config = CompfsConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -91,7 +90,7 @@ impl Builder for CompfsBuilder {
         let core = CompfsCore {
             info: {
                 let am = AccessorInfo::default();
-                am.set_scheme(Scheme::Compfs)
+                am.set_scheme("compfs")
                     .set_root(&root)
                     .set_native_capability(Capability {
                         stat: true,
diff --git a/core/src/services/cos/backend.rs b/core/src/services/cos/backend.rs
index d41365121..e442887a8 100644
--- a/core/src/services/cos/backend.rs
+++ b/core/src/services/cos/backend.rs
@@ -164,7 +164,6 @@ impl CosBuilder {
 }
 
 impl Builder for CosBuilder {
-    const SCHEME: Scheme = Scheme::Cos;
     type Config = CosConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -222,7 +221,7 @@ impl Builder for CosBuilder {
             core: Arc::new(CosCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Cos)
+                    am.set_scheme("cos")
                         .set_root(&root)
                         .set_name(&bucket)
                         .set_native_capability(Capability {
diff --git a/core/src/services/d1/backend.rs b/core/src/services/d1/backend.rs
index b6897aa3e..6e4705791 100644
--- a/core/src/services/d1/backend.rs
+++ b/core/src/services/d1/backend.rs
@@ -135,7 +135,6 @@ impl D1Builder {
 }
 
 impl Builder for D1Builder {
-    const SCHEME: Scheme = Scheme::D1;
     type Config = D1Config;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/dashmap/backend.rs b/core/src/services/dashmap/backend.rs
index 300900785..785eca147 100644
--- a/core/src/services/dashmap/backend.rs
+++ b/core/src/services/dashmap/backend.rs
@@ -67,7 +67,6 @@ impl DashmapBuilder {
 }
 
 impl Builder for DashmapBuilder {
-    const SCHEME: Scheme = Scheme::Dashmap;
     type Config = DashmapConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -101,7 +100,7 @@ pub struct DashmapAccessor {
 impl DashmapAccessor {
     fn new(core: DashmapCore, root: String) -> Self {
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Dashmap);
+        info.set_scheme("dashmap");
         info.set_name("dashmap");
         info.set_root(&root);
         info.set_native_capability(Capability {
diff --git a/core/src/services/dbfs/backend.rs b/core/src/services/dbfs/backend.rs
index 1f4bc908e..80628cd45 100644
--- a/core/src/services/dbfs/backend.rs
+++ b/core/src/services/dbfs/backend.rs
@@ -96,7 +96,6 @@ impl DbfsBuilder {
 }
 
 impl Builder for DbfsBuilder {
-    const SCHEME: Scheme = Scheme::Dbfs;
     type Config = DbfsConfig;
 
     /// Build a DbfsBackend.
@@ -150,7 +149,7 @@ impl Access for DbfsBackend {
 
     fn info(&self) -> Arc<AccessorInfo> {
         let am = AccessorInfo::default();
-        am.set_scheme(Scheme::Dbfs)
+        am.set_scheme("dbfs")
             .set_root(&self.core.root)
             .set_native_capability(Capability {
                 stat: true,
diff --git a/core/src/services/dropbox/builder.rs b/core/src/services/dropbox/builder.rs
index 6c7b624ce..ee80c1856 100644
--- a/core/src/services/dropbox/builder.rs
+++ b/core/src/services/dropbox/builder.rs
@@ -126,7 +126,6 @@ impl DropboxBuilder {
 }
 
 impl Builder for DropboxBuilder {
-    const SCHEME: Scheme = Scheme::Dropbox;
     type Config = DropboxConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -182,7 +181,7 @@ impl Builder for DropboxBuilder {
             core: Arc::new(DropboxCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Dropbox)
+                    am.set_scheme("dropbox")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/etcd/backend.rs b/core/src/services/etcd/backend.rs
index fb3ac36aa..01e67a2ed 100644
--- a/core/src/services/etcd/backend.rs
+++ b/core/src/services/etcd/backend.rs
@@ -136,7 +136,6 @@ impl EtcdBuilder {
 }
 
 impl Builder for EtcdBuilder {
-    const SCHEME: Scheme = Scheme::Etcd;
     type Config = EtcdConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/foundationdb/backend.rs b/core/src/services/foundationdb/backend.rs
index c72099cb1..51f721ce6 100644
--- a/core/src/services/foundationdb/backend.rs
+++ b/core/src/services/foundationdb/backend.rs
@@ -59,7 +59,6 @@ impl FoundationdbBuilder {
 }
 
 impl Builder for FoundationdbBuilder {
-    const SCHEME: Scheme = Scheme::Foundationdb;
     type Config = FoundationdbConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/fs/backend.rs b/core/src/services/fs/backend.rs
index d7d50107f..09c526c0c 100644
--- a/core/src/services/fs/backend.rs
+++ b/core/src/services/fs/backend.rs
@@ -72,7 +72,6 @@ impl FsBuilder {
 }
 
 impl Builder for FsBuilder {
-    const SCHEME: Scheme = Scheme::Fs;
     type Config = FsConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -145,7 +144,7 @@ impl Builder for FsBuilder {
             core: Arc::new(FsCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Fs)
+                    am.set_scheme("fs")
                         .set_root(&root.to_string_lossy())
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/ftp/backend.rs b/core/src/services/ftp/backend.rs
index 9d4ece031..e63b47ce8 100644
--- a/core/src/services/ftp/backend.rs
+++ b/core/src/services/ftp/backend.rs
@@ -109,7 +109,6 @@ impl FtpBuilder {
 }
 
 impl Builder for FtpBuilder {
-    const SCHEME: Scheme = Scheme::Ftp;
     type Config = FtpConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -162,7 +161,7 @@ impl Builder for FtpBuilder {
 
         let accessor_info = AccessorInfo::default();
         accessor_info
-            .set_scheme(Scheme::Ftp)
+            .set_scheme("ftp")
             .set_root(&root)
             .set_native_capability(Capability {
                 stat: true,
diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs
index 4cd49677f..3a067ca33 100644
--- a/core/src/services/gcs/backend.rs
+++ b/core/src/services/gcs/backend.rs
@@ -234,7 +234,6 @@ impl GcsBuilder {
 }
 
 impl Builder for GcsBuilder {
-    const SCHEME: Scheme = Scheme::Gcs;
     type Config = GcsConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -308,7 +307,7 @@ impl Builder for GcsBuilder {
             core: Arc::new(GcsCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Gcs)
+                    am.set_scheme("gcs")
                         .set_root(&root)
                         .set_name(bucket)
                         .set_native_capability(Capability {
diff --git a/core/src/services/gdrive/builder.rs b/core/src/services/gdrive/builder.rs
index 9e9c62b02..532d626e3 100644
--- a/core/src/services/gdrive/builder.rs
+++ b/core/src/services/gdrive/builder.rs
@@ -135,7 +135,6 @@ impl GdriveBuilder {
 }
 
 impl Builder for GdriveBuilder {
-    const SCHEME: Scheme = Scheme::Gdrive;
     type Config = GdriveConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -143,7 +142,7 @@ impl Builder for GdriveBuilder {
         debug!("backend use root {root}");
 
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Gdrive)
+        info.set_scheme("gdrive")
             .set_root(&root)
             .set_native_capability(Capability {
                 stat: true,
diff --git a/core/src/services/ghac/backend.rs b/core/src/services/ghac/backend.rs
index 08a6f6d47..f484f93ca 100644
--- a/core/src/services/ghac/backend.rs
+++ b/core/src/services/ghac/backend.rs
@@ -136,7 +136,6 @@ impl GhacBuilder {
 }
 
 impl Builder for GhacBuilder {
-    const SCHEME: Scheme = Scheme::Ghac;
     type Config = GhacConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -174,7 +173,7 @@ impl Builder for GhacBuilder {
         let core = GhacCore {
             info: {
                 let am = AccessorInfo::default();
-                am.set_scheme(Scheme::Ghac)
+                am.set_scheme("ghac")
                     .set_root(&root)
                     .set_name(&version)
                     .set_native_capability(Capability {
diff --git a/core/src/services/ghac/writer.rs b/core/src/services/ghac/writer.rs
index 51bf5d5a7..e0d550753 100644
--- a/core/src/services/ghac/writer.rs
+++ b/core/src/services/ghac/writer.rs
@@ -68,7 +68,7 @@ impl GhacWriter {
                 let azure_core = Arc::new(AzblobCore {
                     info: {
                         let am = AccessorInfo::default();
-                        am.set_scheme(Scheme::Azblob)
+                        am.set_scheme("azblob")
                             .set_root("/")
                             .set_name(container)
                             .set_native_capability(Capability {
diff --git a/core/src/services/github/backend.rs b/core/src/services/github/backend.rs
index 6830c693c..4237f4825 100644
--- a/core/src/services/github/backend.rs
+++ b/core/src/services/github/backend.rs
@@ -119,7 +119,6 @@ impl GithubBuilder {
 }
 
 impl Builder for GithubBuilder {
-    const SCHEME: Scheme = Scheme::Github;
     type Config = GithubConfig;
 
     /// Builds the backend and returns the result of GithubBackend.
@@ -151,7 +150,7 @@ impl Builder for GithubBuilder {
             core: Arc::new(GithubCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Github)
+                    am.set_scheme("github")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/gridfs/backend.rs b/core/src/services/gridfs/backend.rs
index 9edb239d9..bd24007b2 100644
--- a/core/src/services/gridfs/backend.rs
+++ b/core/src/services/gridfs/backend.rs
@@ -119,7 +119,6 @@ impl GridfsBuilder {
 }
 
 impl Builder for GridfsBuilder {
-    const SCHEME: Scheme = Scheme::Gridfs;
     type Config = GridfsConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/hdfs/backend.rs b/core/src/services/hdfs/backend.rs
index 81e287228..888e8d98c 100644
--- a/core/src/services/hdfs/backend.rs
+++ b/core/src/services/hdfs/backend.rs
@@ -125,7 +125,6 @@ impl HdfsBuilder {
 }
 
 impl Builder for HdfsBuilder {
-    const SCHEME: Scheme = Scheme::Hdfs;
     type Config = HdfsConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -175,7 +174,7 @@ impl Builder for HdfsBuilder {
         Ok(HdfsBackend {
             info: {
                 let am = AccessorInfo::default();
-                am.set_scheme(Scheme::Hdfs)
+                am.set_scheme("hdfs")
                     .set_root(&root)
                     .set_native_capability(Capability {
                         stat: true,
diff --git a/core/src/services/hdfs_native/backend.rs b/core/src/services/hdfs_native/backend.rs
index 99e485739..adf0e0054 100644
--- a/core/src/services/hdfs_native/backend.rs
+++ b/core/src/services/hdfs_native/backend.rs
@@ -94,7 +94,6 @@ impl HdfsNativeBuilder {
 }
 
 impl Builder for HdfsNativeBuilder {
-    const SCHEME: Scheme = Scheme::HdfsNative;
     type Config = HdfsNativeConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -150,7 +149,7 @@ impl Access for HdfsNativeBackend {
 
     fn info(&self) -> Arc<AccessorInfo> {
         let am = AccessorInfo::default();
-        am.set_scheme(Scheme::HdfsNative)
+        am.set_scheme("hdfs_native")
             .set_root(&self.root)
             .set_native_capability(Capability {
                 stat: true,
diff --git a/core/src/services/http/backend.rs b/core/src/services/http/backend.rs
index 0ee448a7e..023424a36 100644
--- a/core/src/services/http/backend.rs
+++ b/core/src/services/http/backend.rs
@@ -129,7 +129,6 @@ impl HttpBuilder {
 }
 
 impl Builder for HttpBuilder {
-    const SCHEME: Scheme = Scheme::Http;
     type Config = HttpConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -158,7 +157,7 @@ impl Builder for HttpBuilder {
         }
 
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Http)
+        info.set_scheme("http")
             .set_root(&root)
             .set_native_capability(Capability {
                 stat: true,
diff --git a/core/src/services/huggingface/backend.rs b/core/src/services/huggingface/backend.rs
index 43aad0156..c3d70cbf0 100644
--- a/core/src/services/huggingface/backend.rs
+++ b/core/src/services/huggingface/backend.rs
@@ -126,7 +126,6 @@ impl HuggingfaceBuilder {
 }
 
 impl Builder for HuggingfaceBuilder {
-    const SCHEME: Scheme = Scheme::Huggingface;
     type Config = HuggingfaceConfig;
 
     /// Build a HuggingfaceBackend.
@@ -173,7 +172,7 @@ impl Builder for HuggingfaceBuilder {
             core: Arc::new(HuggingfaceCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Huggingface)
+                    am.set_scheme("huggingface")
                         .set_native_capability(Capability {
                             stat: true,
 
diff --git a/core/src/services/ipfs/backend.rs b/core/src/services/ipfs/backend.rs
index c8877c6cf..21737adfe 100644
--- a/core/src/services/ipfs/backend.rs
+++ b/core/src/services/ipfs/backend.rs
@@ -106,7 +106,6 @@ impl IpfsBuilder {
 }
 
 impl Builder for IpfsBuilder {
-    const SCHEME: Scheme = Scheme::Ipfs;
     type Config = IpfsConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -132,7 +131,7 @@ impl Builder for IpfsBuilder {
         debug!("backend use endpoint {}", &endpoint);
 
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Ipfs)
+        info.set_scheme("ipfs")
             .set_root(&root)
             .set_native_capability(Capability {
                 stat: true,
diff --git a/core/src/services/ipmfs/builder.rs b/core/src/services/ipmfs/builder.rs
index f87fa2715..6d047b2af 100644
--- a/core/src/services/ipmfs/builder.rs
+++ b/core/src/services/ipmfs/builder.rs
@@ -124,7 +124,6 @@ impl IpmfsBuilder {
 }
 
 impl Builder for IpmfsBuilder {
-    const SCHEME: Scheme = Scheme::Ipmfs;
     type Config = IpmfsConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -138,7 +137,7 @@ impl Builder for IpmfsBuilder {
             .unwrap_or_else(|| "http://localhost:5001".to_string());
 
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Ipmfs)
+        info.set_scheme("ipmfs")
             .set_root(&root)
             .set_native_capability(Capability {
                 stat: true,
diff --git a/core/src/services/koofr/backend.rs b/core/src/services/koofr/backend.rs
index 99b7b8d19..ff92fd141 100644
--- a/core/src/services/koofr/backend.rs
+++ b/core/src/services/koofr/backend.rs
@@ -136,7 +136,6 @@ impl KoofrBuilder {
 }
 
 impl Builder for KoofrBuilder {
-    const SCHEME: Scheme = Scheme::Koofr;
     type Config = KoofrConfig;
 
     /// Builds the backend and returns the result of KoofrBackend.
@@ -175,7 +174,7 @@ impl Builder for KoofrBuilder {
             core: Arc::new(KoofrCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Koofr)
+                    am.set_scheme("koofr")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/lakefs/backend.rs b/core/src/services/lakefs/backend.rs
index 732251841..ce992e231 100644
--- a/core/src/services/lakefs/backend.rs
+++ b/core/src/services/lakefs/backend.rs
@@ -126,7 +126,6 @@ impl LakefsBuilder {
 }
 
 impl Builder for LakefsBuilder {
-    const SCHEME: Scheme = Scheme::Lakefs;
     type Config = LakefsConfig;
 
     /// Build a LakefsBackend.
@@ -176,19 +175,18 @@ impl Builder for LakefsBuilder {
             core: Arc::new(LakefsCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Lakefs)
-                        .set_native_capability(Capability {
-                            stat: true,
-
-                            list: true,
-
-                            read: true,
-                            write: true,
-                            delete: true,
-                            copy: true,
-                            shared: true,
-                            ..Default::default()
-                        });
+                    am.set_scheme("lakefs").set_native_capability(Capability {
+                        stat: true,
+
+                        list: true,
+
+                        read: true,
+                        write: true,
+                        delete: true,
+                        copy: true,
+                        shared: true,
+                        ..Default::default()
+                    });
                     am.into()
                 },
                 endpoint,
diff --git a/core/src/services/memcached/backend.rs b/core/src/services/memcached/backend.rs
index caa29cff1..23e5d2870 100644
--- a/core/src/services/memcached/backend.rs
+++ b/core/src/services/memcached/backend.rs
@@ -85,7 +85,6 @@ impl MemcachedBuilder {
 }
 
 impl Builder for MemcachedBuilder {
-    const SCHEME: Scheme = Scheme::Memcached;
     type Config = MemcachedConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/memory/backend.rs b/core/src/services/memory/backend.rs
index 48f5e07df..68d4c706f 100644
--- a/core/src/services/memory/backend.rs
+++ b/core/src/services/memory/backend.rs
@@ -50,7 +50,6 @@ impl MemoryBuilder {
 }
 
 impl Builder for MemoryBuilder {
-    const SCHEME: Scheme = Scheme::Memory;
     type Config = MemoryConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -72,7 +71,7 @@ pub struct MemoryAccessor {
 impl MemoryAccessor {
     fn new(core: MemoryCore) -> Self {
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Memory);
+        info.set_scheme("memory");
         info.set_name(&format!("{:p}", Arc::as_ptr(&core.data)));
         info.set_root("/");
         info.set_native_capability(Capability {
diff --git a/core/src/services/mini_moka/backend.rs b/core/src/services/mini_moka/backend.rs
index 042c627ed..78ccbc9f5 100644
--- a/core/src/services/mini_moka/backend.rs
+++ b/core/src/services/mini_moka/backend.rs
@@ -103,7 +103,6 @@ impl MiniMokaBuilder {
 }
 
 impl Builder for MiniMokaBuilder {
-    const SCHEME: Scheme = Scheme::MiniMoka;
     type Config = MiniMokaConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -156,7 +155,7 @@ impl Access for MiniMokaBackend {
 
     fn info(&self) -> Arc<AccessorInfo> {
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::MiniMoka)
+        info.set_scheme("mini_moka")
             .set_root(&self.root)
             .set_native_capability(Capability {
                 stat: true,
diff --git a/core/src/services/moka/backend.rs b/core/src/services/moka/backend.rs
index a685ca12e..aeb670c4f 100644
--- a/core/src/services/moka/backend.rs
+++ b/core/src/services/moka/backend.rs
@@ -151,7 +151,6 @@ impl MokaBuilder {
 }
 
 impl Builder for MokaBuilder {
-    const SCHEME: Scheme = Scheme::Moka;
     type Config = MokaConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -203,7 +202,7 @@ pub struct MokaAccessor {
 impl MokaAccessor {
     fn new(core: MokaCore) -> Self {
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Moka);
+        info.set_scheme("moka");
         info.set_name(core.cache.name().unwrap_or("moka"));
         info.set_root("/");
         info.set_native_capability(Capability {
diff --git a/core/src/services/mongodb/backend.rs b/core/src/services/mongodb/backend.rs
index a3edd88df..442b7d958 100644
--- a/core/src/services/mongodb/backend.rs
+++ b/core/src/services/mongodb/backend.rs
@@ -128,7 +128,6 @@ impl MongodbBuilder {
 }
 
 impl Builder for MongodbBuilder {
-    const SCHEME: Scheme = Scheme::Mongodb;
     type Config = MongodbConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/monoiofs/backend.rs b/core/src/services/monoiofs/backend.rs
index 0894f133f..ad2833fa4 100644
--- a/core/src/services/monoiofs/backend.rs
+++ b/core/src/services/monoiofs/backend.rs
@@ -61,7 +61,6 @@ impl MonoiofsBuilder {
 }
 
 impl Builder for MonoiofsBuilder {
-    const SCHEME: Scheme = Scheme::Monoiofs;
     type Config = MonoiofsConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/monoiofs/core.rs b/core/src/services/monoiofs/core.rs
index 0428719cb..4bd0fe348 100644
--- a/core/src/services/monoiofs/core.rs
+++ b/core/src/services/monoiofs/core.rs
@@ -69,7 +69,7 @@ impl MonoiofsCore {
         Self {
             info: {
                 let am = AccessorInfo::default();
-                am.set_scheme(Scheme::Monoiofs)
+                am.set_scheme("monoiofs")
                     .set_root(&root.to_string_lossy())
                     .set_native_capability(Capability {
                         stat: true,
diff --git a/core/src/services/mysql/backend.rs b/core/src/services/mysql/backend.rs
index ad4ad4374..120ae4b58 100644
--- a/core/src/services/mysql/backend.rs
+++ b/core/src/services/mysql/backend.rs
@@ -113,7 +113,6 @@ impl MysqlBuilder {
 }
 
 impl Builder for MysqlBuilder {
-    const SCHEME: Scheme = Scheme::Mysql;
     type Config = MysqlConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/obs/backend.rs b/core/src/services/obs/backend.rs
index e88607f08..f89d148d9 100644
--- a/core/src/services/obs/backend.rs
+++ b/core/src/services/obs/backend.rs
@@ -154,7 +154,6 @@ impl ObsBuilder {
 }
 
 impl Builder for ObsBuilder {
-    const SCHEME: Scheme = Scheme::Obs;
     type Config = ObsConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -233,7 +232,7 @@ impl Builder for ObsBuilder {
             core: Arc::new(ObsCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Obs)
+                    am.set_scheme("obs")
                         .set_root(&root)
                         .set_name(&bucket)
                         .set_native_capability(Capability {
diff --git a/core/src/services/onedrive/builder.rs b/core/src/services/onedrive/builder.rs
index 4d2d4c91d..142a91a69 100644
--- a/core/src/services/onedrive/builder.rs
+++ b/core/src/services/onedrive/builder.rs
@@ -137,7 +137,6 @@ impl OnedriveBuilder {
 }
 
 impl Builder for OnedriveBuilder {
-    const SCHEME: Scheme = Scheme::Onedrive;
     type Config = OnedriveConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -145,7 +144,7 @@ impl Builder for OnedriveBuilder {
         debug!("backend use root {root}");
 
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Onedrive)
+        info.set_scheme("onedrive")
             .set_root(&root)
             .set_native_capability(Capability {
                 read: true,
diff --git a/core/src/services/oss/backend.rs b/core/src/services/oss/backend.rs
index ec6ea73c0..56e841eaf 100644
--- a/core/src/services/oss/backend.rs
+++ b/core/src/services/oss/backend.rs
@@ -318,7 +318,6 @@ impl OssBuilder {
 }
 
 impl Builder for OssBuilder {
-    const SCHEME: Scheme = Scheme::Oss;
     type Config = OssConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -411,7 +410,7 @@ impl Builder for OssBuilder {
             core: Arc::new(OssCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Oss)
+                    am.set_scheme("oss")
                         .set_root(&root)
                         .set_name(bucket)
                         .set_native_capability(Capability {
diff --git a/core/src/services/pcloud/backend.rs b/core/src/services/pcloud/backend.rs
index 6caaaeb4c..fdc4d2fb5 100644
--- a/core/src/services/pcloud/backend.rs
+++ b/core/src/services/pcloud/backend.rs
@@ -132,7 +132,6 @@ impl PcloudBuilder {
 }
 
 impl Builder for PcloudBuilder {
-    const SCHEME: Scheme = Scheme::Pcloud;
     type Config = PcloudConfig;
 
     /// Builds the backend and returns the result of PcloudBackend.
@@ -169,7 +168,7 @@ impl Builder for PcloudBuilder {
             core: Arc::new(PcloudCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Pcloud)
+                    am.set_scheme("pcloud")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/persy/backend.rs b/core/src/services/persy/backend.rs
index 934db41c8..f1cfdc725 100644
--- a/core/src/services/persy/backend.rs
+++ b/core/src/services/persy/backend.rs
@@ -65,7 +65,6 @@ impl PersyBuilder {
 }
 
 impl Builder for PersyBuilder {
-    const SCHEME: Scheme = Scheme::Persy;
     type Config = PersyConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/postgresql/backend.rs b/core/src/services/postgresql/backend.rs
index ab4570909..1214c3351 100644
--- a/core/src/services/postgresql/backend.rs
+++ b/core/src/services/postgresql/backend.rs
@@ -112,7 +112,6 @@ impl PostgresqlBuilder {
 }
 
 impl Builder for PostgresqlBuilder {
-    const SCHEME: Scheme = Scheme::Postgresql;
     type Config = PostgresqlConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/redb/backend.rs b/core/src/services/redb/backend.rs
index 31de507db..18c3d0b26 100644
--- a/core/src/services/redb/backend.rs
+++ b/core/src/services/redb/backend.rs
@@ -97,7 +97,6 @@ impl RedbBuilder {
 }
 
 impl Builder for RedbBuilder {
-    const SCHEME: Scheme = Scheme::Redb;
     type Config = RedbConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/redis/backend.rs b/core/src/services/redis/backend.rs
index e6817c493..b37b9029d 100644
--- a/core/src/services/redis/backend.rs
+++ b/core/src/services/redis/backend.rs
@@ -144,7 +144,6 @@ impl RedisBuilder {
 }
 
 impl Builder for RedisBuilder {
-    const SCHEME: Scheme = Scheme::Redis;
     type Config = RedisConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -278,7 +277,7 @@ pub struct RedisAccessor {
 impl RedisAccessor {
     fn new(core: RedisCore) -> Self {
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Redis);
+        info.set_scheme("redis");
         info.set_name(&core.addr);
         info.set_root("/");
         info.set_native_capability(Capability {
@@ -396,7 +395,7 @@ mod tests {
 
         // Verify basic properties
         assert_eq!(accessor.root, "/");
-        assert_eq!(accessor.info.scheme(), Scheme::Redis);
+        assert_eq!(accessor.info.scheme(), "redis");
         assert!(accessor.info.native_capability().read);
         assert!(accessor.info.native_capability().write);
         assert!(accessor.info.native_capability().delete);
diff --git a/core/src/services/rocksdb/backend.rs b/core/src/services/rocksdb/backend.rs
index 68c481ba5..bba240434 100644
--- a/core/src/services/rocksdb/backend.rs
+++ b/core/src/services/rocksdb/backend.rs
@@ -63,7 +63,6 @@ impl RocksdbBuilder {
 }
 
 impl Builder for RocksdbBuilder {
-    const SCHEME: Scheme = Scheme::Rocksdb;
     type Config = RocksdbConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/s3/backend.rs b/core/src/services/s3/backend.rs
index a36ff1a41..bb9d0cf9d 100644
--- a/core/src/services/s3/backend.rs
+++ b/core/src/services/s3/backend.rs
@@ -716,7 +716,6 @@ impl S3Builder {
 }
 
 impl Builder for S3Builder {
-    const SCHEME: Scheme = Scheme::S3;
     type Config = S3Config;
 
     fn build(mut self) -> Result<impl Access> {
@@ -904,7 +903,7 @@ impl Builder for S3Builder {
             core: Arc::new(S3Core {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::S3)
+                    am.set_scheme("s3")
                         .set_root(&root)
                         .set_name(bucket)
                         .set_native_capability(Capability {
diff --git a/core/src/services/seafile/backend.rs b/core/src/services/seafile/backend.rs
index 5c1dc21a5..a53bc7db5 100644
--- a/core/src/services/seafile/backend.rs
+++ b/core/src/services/seafile/backend.rs
@@ -145,7 +145,6 @@ impl SeafileBuilder {
 }
 
 impl Builder for SeafileBuilder {
-    const SCHEME: Scheme = Scheme::Seafile;
     type Config = SeafileConfig;
 
     /// Builds the backend and returns the result of SeafileBackend.
@@ -189,7 +188,7 @@ impl Builder for SeafileBuilder {
             core: Arc::new(SeafileCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Seafile)
+                    am.set_scheme("seafile")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/sftp/backend.rs b/core/src/services/sftp/backend.rs
index 96c5fa60d..2497e6541 100644
--- a/core/src/services/sftp/backend.rs
+++ b/core/src/services/sftp/backend.rs
@@ -141,7 +141,6 @@ impl SftpBuilder {
 }
 
 impl Builder for SftpBuilder {
-    const SCHEME: Scheme = Scheme::Sftp;
     type Config = SftpConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -181,7 +180,7 @@ impl Builder for SftpBuilder {
 
         let info = AccessorInfo::default();
         info.set_root(root.as_str())
-            .set_scheme(Scheme::Sftp)
+            .set_scheme("sftp")
             .set_native_capability(Capability {
                 stat: true,
 
diff --git a/core/src/services/sled/backend.rs b/core/src/services/sled/backend.rs
index 3e366f363..7f9dd7306 100644
--- a/core/src/services/sled/backend.rs
+++ b/core/src/services/sled/backend.rs
@@ -79,7 +79,6 @@ impl SledBuilder {
 }
 
 impl Builder for SledBuilder {
-    const SCHEME: Scheme = Scheme::Sled;
     type Config = SledConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/sqlite/backend.rs b/core/src/services/sqlite/backend.rs
index cfda82bc1..5fac36b4d 100644
--- a/core/src/services/sqlite/backend.rs
+++ b/core/src/services/sqlite/backend.rs
@@ -121,7 +121,6 @@ impl SqliteBuilder {
 }
 
 impl Builder for SqliteBuilder {
-    const SCHEME: Scheme = Scheme::Sqlite;
     type Config = SqliteConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/surrealdb/backend.rs b/core/src/services/surrealdb/backend.rs
index 3026a9c4e..8192815fb 100644
--- a/core/src/services/surrealdb/backend.rs
+++ b/core/src/services/surrealdb/backend.rs
@@ -144,7 +144,6 @@ impl SurrealdbBuilder {
 }
 
 impl Builder for SurrealdbBuilder {
-    const SCHEME: Scheme = Scheme::Surrealdb;
     type Config = SurrealdbConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/swift/backend.rs b/core/src/services/swift/backend.rs
index d48704b84..4f2b17a7c 100644
--- a/core/src/services/swift/backend.rs
+++ b/core/src/services/swift/backend.rs
@@ -113,7 +113,6 @@ impl SwiftBuilder {
 }
 
 impl Builder for SwiftBuilder {
-    const SCHEME: Scheme = Scheme::Swift;
     type Config = SwiftConfig;
 
     /// Build a SwiftBackend.
@@ -156,7 +155,7 @@ impl Builder for SwiftBuilder {
             core: Arc::new(SwiftCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Swift)
+                    am.set_scheme("swift")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/tikv/backend.rs b/core/src/services/tikv/backend.rs
index 799a811a7..77789087c 100644
--- a/core/src/services/tikv/backend.rs
+++ b/core/src/services/tikv/backend.rs
@@ -96,7 +96,6 @@ impl TikvBuilder {
 }
 
 impl Builder for TikvBuilder {
-    const SCHEME: Scheme = Scheme::Tikv;
     type Config = TikvConfig;
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/services/upyun/backend.rs b/core/src/services/upyun/backend.rs
index 1548bf83d..894e7a439 100644
--- a/core/src/services/upyun/backend.rs
+++ b/core/src/services/upyun/backend.rs
@@ -128,7 +128,6 @@ impl UpyunBuilder {
 }
 
 impl Builder for UpyunBuilder {
-    const SCHEME: Scheme = Scheme::Upyun;
     type Config = UpyunConfig;
 
     /// Builds the backend and returns the result of UpyunBackend.
@@ -170,7 +169,7 @@ impl Builder for UpyunBuilder {
             core: Arc::new(UpyunCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::Upyun)
+                    am.set_scheme("upyun")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/vercel_artifacts/builder.rs b/core/src/services/vercel_artifacts/builder.rs
index 298866172..ccc14e268 100644
--- a/core/src/services/vercel_artifacts/builder.rs
+++ b/core/src/services/vercel_artifacts/builder.rs
@@ -25,7 +25,6 @@ use crate::raw::Access;
 use crate::raw::AccessorInfo;
 use crate::raw::HttpClient;
 use crate::services::VercelArtifactsConfig;
-use crate::Scheme;
 use crate::*;
 
 impl Configurator for VercelArtifactsConfig {
@@ -82,12 +81,11 @@ impl VercelArtifactsBuilder {
 }
 
 impl Builder for VercelArtifactsBuilder {
-    const SCHEME: Scheme = Scheme::VercelArtifacts;
     type Config = VercelArtifactsConfig;
 
     fn build(self) -> Result<impl Access> {
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::VercelArtifacts)
+        info.set_scheme("vercel_artifacts")
             .set_native_capability(Capability {
                 stat: true,
 
diff --git a/core/src/services/vercel_blob/backend.rs b/core/src/services/vercel_blob/backend.rs
index 60aeeeb3d..7f3fbe47f 100644
--- a/core/src/services/vercel_blob/backend.rs
+++ b/core/src/services/vercel_blob/backend.rs
@@ -107,7 +107,6 @@ impl VercelBlobBuilder {
 }
 
 impl Builder for VercelBlobBuilder {
-    const SCHEME: Scheme = Scheme::VercelBlob;
     type Config = VercelBlobConfig;
 
     /// Builds the backend and returns the result of VercelBlobBackend.
@@ -128,7 +127,7 @@ impl Builder for VercelBlobBuilder {
             core: Arc::new(VercelBlobCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::VercelBlob)
+                    am.set_scheme("vercel_blob")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/services/webdav/backend.rs b/core/src/services/webdav/backend.rs
index c88b711d1..c21a6adb0 100644
--- a/core/src/services/webdav/backend.rs
+++ b/core/src/services/webdav/backend.rs
@@ -135,7 +135,6 @@ impl WebdavBuilder {
 }
 
 impl Builder for WebdavBuilder {
-    const SCHEME: Scheme = Scheme::Webdav;
     type Config = WebdavConfig;
 
     fn build(self) -> Result<impl Access> {
@@ -176,7 +175,7 @@ impl Builder for WebdavBuilder {
         let core = Arc::new(WebdavCore {
             info: {
                 let am = AccessorInfo::default();
-                am.set_scheme(Scheme::Webdav)
+                am.set_scheme("webdav")
                     .set_root(&root)
                     .set_native_capability(Capability {
                         stat: true,
diff --git a/core/src/services/webhdfs/backend.rs b/core/src/services/webhdfs/backend.rs
index 8f8ca704f..95c537fcf 100644
--- a/core/src/services/webhdfs/backend.rs
+++ b/core/src/services/webhdfs/backend.rs
@@ -147,7 +147,6 @@ impl WebhdfsBuilder {
 }
 
 impl Builder for WebhdfsBuilder {
-    const SCHEME: Scheme = Scheme::Webhdfs;
     type Config = WebhdfsConfig;
 
     /// build the backend
@@ -181,7 +180,7 @@ impl Builder for WebhdfsBuilder {
         let auth = self.config.delegation.map(|dt| format!("delegation={dt}"));
 
         let info = AccessorInfo::default();
-        info.set_scheme(Scheme::Webhdfs)
+        info.set_scheme("webhdfs")
             .set_root(&root)
             .set_native_capability(Capability {
                 stat: true,
diff --git a/core/src/services/yandex_disk/backend.rs b/core/src/services/yandex_disk/backend.rs
index 79b1dcf16..9366097d6 100644
--- a/core/src/services/yandex_disk/backend.rs
+++ b/core/src/services/yandex_disk/backend.rs
@@ -104,7 +104,6 @@ impl YandexDiskBuilder {
 }
 
 impl Builder for YandexDiskBuilder {
-    const SCHEME: Scheme = Scheme::YandexDisk;
     type Config = YandexDiskConfig;
 
     /// Builds the backend and returns the result of YandexDiskBackend.
@@ -127,7 +126,7 @@ impl Builder for YandexDiskBuilder {
             core: Arc::new(YandexDiskCore {
                 info: {
                     let am = AccessorInfo::default();
-                    am.set_scheme(Scheme::YandexDisk)
+                    am.set_scheme("yandex_disk")
                         .set_root(&root)
                         .set_native_capability(Capability {
                             stat: true,
diff --git a/core/src/types/builder.rs b/core/src/types/builder.rs
index 43b05e582..3490913cb 100644
--- a/core/src/types/builder.rs
+++ b/core/src/types/builder.rs
@@ -49,8 +49,6 @@ use crate::*;
 /// }
 /// ```
 pub trait Builder: Default + 'static {
-    /// Associated scheme for this builder. It indicates what underlying service is.
-    const SCHEME: Scheme;
     /// Associated configuration for this builder.
     type Config: Configurator;
 
@@ -60,7 +58,6 @@ pub trait Builder: Default + 'static {
 
 /// Dummy implementation of builder
 impl Builder for () {
-    const SCHEME: Scheme = Scheme::Custom("dummy");
     type Config = ();
 
     fn build(self) -> Result<impl Access> {
diff --git a/core/src/types/operator/info.rs b/core/src/types/operator/info.rs
index dfe7b298c..2e483f450 100644
--- a/core/src/types/operator/info.rs
+++ b/core/src/types/operator/info.rs
@@ -15,6 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use std::str::FromStr;
 use std::sync::Arc;
 
 use crate::raw::*;
@@ -31,7 +32,8 @@ impl OperatorInfo {
 
     /// [`Scheme`] of operator.
     pub fn scheme(&self) -> Scheme {
-        self.0.scheme()
+        let scheme_str = self.0.scheme();
+        Scheme::from_str(scheme_str).unwrap_or(Scheme::Custom(scheme_str))
     }
 
     /// Root of operator, will be in format like `/path/to/dir/`
diff --git a/core/src/types/operator/operator.rs b/core/src/types/operator/operator.rs
index 90f1bd8b2..f27306f3a 100644
--- a/core/src/types/operator/operator.rs
+++ b/core/src/types/operator/operator.rs
@@ -1004,7 +1004,7 @@ impl Operator {
             return Err(
                 Error::new(ErrorKind::IsADirectory, "write path is a directory")
                     .with_operation("Operator::writer")
-                    .with_context("service", acc.info().scheme().into_static())
+                    .with_context("service", acc.info().scheme())
                     .with_context("path", &path),
             );
         }