diff --git a/bin/oay/src/services/s3/service.rs b/bin/oay/src/services/s3/service.rs index a4113011215..56a4a4d6ad6 100644 --- a/bin/oay/src/services/s3/service.rs +++ b/bin/oay/src/services/s3/service.rs @@ -88,7 +88,7 @@ async fn handle_list_objects( ) -> Result { debug!("got params: {:?}", params); - if !state.op.info().capability().list_with_start_after { + if !state.op.info().full_capability().list_with_start_after { return Err(ErrorResponse { code: StatusCode::NOT_IMPLEMENTED, err: Error { diff --git a/core/src/layers/blocking.rs b/core/src/layers/blocking.rs index c6fe23bb96f..47dbcba40c1 100644 --- a/core/src/layers/blocking.rs +++ b/core/src/layers/blocking.rs @@ -80,10 +80,9 @@ impl LayeredAccessor for BlockingAccessor { } fn metadata(&self) -> AccessorInfo { - let mut info = self.inner.info(); - let cap = info.capability_mut(); - cap.blocking = true; - info + let mut meta = self.inner.info(); + meta.full_capability_mut().blocking = true; + meta } async fn create_dir(&self, path: &str, args: OpCreateDir) -> Result { diff --git a/core/src/layers/complete.rs b/core/src/layers/complete.rs index d30da0b5549..0dda5965c55 100644 --- a/core/src/layers/complete.rs +++ b/core/src/layers/complete.rs @@ -131,9 +131,8 @@ impl Layer for CompleteLayer { type LayeredAccessor = CompleteReaderAccessor; fn layer(&self, inner: A) -> Self::LayeredAccessor { - let meta = inner.info(); CompleteReaderAccessor { - meta, + meta: inner.info(), inner: Arc::new(inner), } } @@ -157,7 +156,7 @@ impl CompleteReaderAccessor { path: &str, args: OpRead, ) -> Result<(RpRead, CompleteReader)> { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.read { return new_capability_unsupported_error(Operation::Read); } @@ -210,7 +209,7 @@ impl CompleteReaderAccessor { path: &str, args: OpRead, ) -> Result<(RpRead, CompleteReader)> { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.read || !capability.blocking { return new_capability_unsupported_error(Operation::BlockingRead); } @@ -266,7 +265,7 @@ impl CompleteReaderAccessor { path: &str, args: OpList, ) -> Result<(RpList, CompletePager)> { - let cap = self.meta.capability(); + let cap = self.meta.full_capability(); if !cap.list { return Err( Error::new(ErrorKind::Unsupported, "operation is not supported") @@ -315,7 +314,7 @@ impl CompleteReaderAccessor { path: &str, args: OpList, ) -> Result<(RpList, CompletePager)> { - let cap = self.meta.capability(); + let cap = self.meta.full_capability(); if !cap.list { return Err( Error::new(ErrorKind::Unsupported, "operation is not supported") @@ -376,6 +375,16 @@ impl LayeredAccessor for CompleteReaderAccessor { &self.inner } + fn metadata(&self) -> AccessorInfo { + let mut meta = self.meta.clone(); + let cap = meta.full_capability_mut(); + if cap.read { + cap.read_can_next = true; + cap.read_can_seek = true; + } + meta + } + async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> { self.complete_reader(path, args).await } @@ -385,7 +394,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } async fn stat(&self, path: &str, args: OpStat) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.stat { return new_capability_unsupported_error(Operation::Stat); } @@ -399,7 +408,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } fn blocking_stat(&self, path: &str, args: OpStat) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.stat || !capability.blocking { return new_capability_unsupported_error(Operation::BlockingStat); } @@ -413,7 +422,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } async fn write(&self, path: &str, args: OpWrite) -> Result<(RpWrite, Self::Writer)> { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.write { return new_capability_unsupported_error(Operation::Write); } @@ -426,7 +435,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } fn blocking_write(&self, path: &str, args: OpWrite) -> Result<(RpWrite, Self::BlockingWriter)> { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.write || !capability.blocking { return new_capability_unsupported_error(Operation::BlockingWrite); } @@ -438,7 +447,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } async fn append(&self, path: &str, args: OpAppend) -> Result<(RpAppend, Self::Appender)> { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.append { return new_capability_unsupported_error(Operation::Append); } @@ -450,7 +459,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } async fn create_dir(&self, path: &str, args: OpCreateDir) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.create_dir { return new_capability_unsupported_error(Operation::CreateDir); } @@ -459,7 +468,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } fn blocking_create_dir(&self, path: &str, args: OpCreateDir) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.create_dir || !capability.blocking { return new_capability_unsupported_error(Operation::BlockingCreateDir); } @@ -468,7 +477,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } async fn delete(&self, path: &str, args: OpDelete) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.delete { return new_capability_unsupported_error(Operation::Delete); } @@ -477,7 +486,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } fn blocking_delete(&self, path: &str, args: OpDelete) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.delete || !capability.blocking { return new_capability_unsupported_error(Operation::BlockingDelete); } @@ -486,7 +495,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } async fn copy(&self, from: &str, to: &str, args: OpCopy) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.copy { return new_capability_unsupported_error(Operation::Copy); } @@ -495,7 +504,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } fn blocking_copy(&self, from: &str, to: &str, args: OpCopy) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.copy || !capability.blocking { return new_capability_unsupported_error(Operation::BlockingCopy); } @@ -504,7 +513,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } async fn rename(&self, from: &str, to: &str, args: OpRename) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.rename { return new_capability_unsupported_error(Operation::Rename); } @@ -513,7 +522,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } fn blocking_rename(&self, from: &str, to: &str, args: OpRename) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.rename || !capability.blocking { return new_capability_unsupported_error(Operation::BlockingRename); } @@ -522,7 +531,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } async fn list(&self, path: &str, args: OpList) -> Result<(RpList, Self::Pager)> { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.list { return new_capability_unsupported_error(Operation::List); } @@ -531,7 +540,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } fn blocking_list(&self, path: &str, args: OpList) -> Result<(RpList, Self::BlockingPager)> { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.list || !capability.blocking { return new_capability_unsupported_error(Operation::BlockingList); } @@ -540,7 +549,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } async fn presign(&self, path: &str, args: OpPresign) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.presign { return new_capability_unsupported_error(Operation::Presign); } @@ -549,7 +558,7 @@ impl LayeredAccessor for CompleteReaderAccessor { } async fn batch(&self, args: OpBatch) -> Result { - let capability = self.meta.capability(); + let capability = self.meta.full_capability(); if !capability.batch { return new_capability_unsupported_error(Operation::Batch); } @@ -952,7 +961,7 @@ mod tests { fn info(&self) -> AccessorInfo { let mut info = AccessorInfo::default(); - info.set_capability(self.capability); + info.set_full_capability(self.capability); info } diff --git a/core/src/layers/immutable_index.rs b/core/src/layers/immutable_index.rs index 3744821511b..dc167fbb5b4 100644 --- a/core/src/layers/immutable_index.rs +++ b/core/src/layers/immutable_index.rs @@ -152,7 +152,7 @@ impl LayeredAccessor for ImmutableIndexAccessor { fn metadata(&self) -> AccessorInfo { let mut meta = self.inner.info(); - let cap = meta.capability_mut(); + let cap = meta.full_capability_mut(); cap.list = true; cap.list_with_delimiter_slash = true; cap.list_without_delimiter = true; diff --git a/core/src/layers/madsim.rs b/core/src/layers/madsim.rs index 40b18d78580..87d726c9961 100644 --- a/core/src/layers/madsim.rs +++ b/core/src/layers/madsim.rs @@ -161,7 +161,7 @@ impl LayeredAccessor for MadsimAccessor { let mut info = AccessorInfo::default(); info.set_name("madsim"); - info.set_capability(Capability { + info.set_full_capability(Capability { read: true, write: true, ..Default::default() diff --git a/core/src/layers/retry.rs b/core/src/layers/retry.rs index e6d083a4d4d..d9febab02d3 100644 --- a/core/src/layers/retry.rs +++ b/core/src/layers/retry.rs @@ -1179,7 +1179,7 @@ mod tests { fn info(&self) -> AccessorInfo { let mut am = AccessorInfo::default(); - am.set_capability(Capability { + am.set_full_capability(Capability { read: true, list: true, list_with_delimiter_slash: true, diff --git a/core/src/raw/accessor.rs b/core/src/raw/accessor.rs index b6b74a15994..ad8d3b095ae 100644 --- a/core/src/raw/accessor.rs +++ b/core/src/raw/accessor.rs @@ -398,7 +398,8 @@ impl Accessor for () { scheme: Scheme::Custom("dummy"), root: "".to_string(), name: "dummy".to_string(), - capability: Capability::default(), + native_capability: Capability::default(), + full_capability: Capability::default(), } } } @@ -509,7 +510,8 @@ pub struct AccessorInfo { root: String, name: String, - capability: Capability, + native_capability: Capability, + full_capability: Capability, } impl AccessorInfo { @@ -553,19 +555,24 @@ impl AccessorInfo { self } - /// Get backend's capabilities. - pub fn capability(&self) -> Capability { - self.capability + /// Get backend's native capabilities. + pub fn native_capability(&self) -> Capability { + self.native_capability } - /// Get backend's capabilities. - pub fn capability_mut(&mut self) -> &mut Capability { - &mut self.capability + /// Get service's full capabilities. + pub fn full_capability(&self) -> Capability { + self.full_capability } - /// Set capabilities for backend. - pub fn set_capability(&mut self, capability: Capability) -> &mut Self { - self.capability = capability; + /// Get service's full capabilities. + pub fn full_capability_mut(&mut self) -> &mut Capability { + &mut self.full_capability + } + + /// Set full capabilities for service. + pub fn set_full_capability(&mut self, capability: Capability) -> &mut Self { + self.full_capability = capability; self } } diff --git a/core/src/raw/adapters/kv/api.rs b/core/src/raw/adapters/kv/api.rs index 0c1ad4f959c..7ae2fe97eb8 100644 --- a/core/src/raw/adapters/kv/api.rs +++ b/core/src/raw/adapters/kv/api.rs @@ -169,7 +169,7 @@ impl From for AccessorInfo { let mut am = AccessorInfo::default(); am.set_name(m.name()); am.set_scheme(m.scheme()); - am.set_capability(m.capabilities()); + am.set_full_capability(m.capabilities()); am } diff --git a/core/src/raw/adapters/kv/backend.rs b/core/src/raw/adapters/kv/backend.rs index 42bfed62d51..91417d59585 100644 --- a/core/src/raw/adapters/kv/backend.rs +++ b/core/src/raw/adapters/kv/backend.rs @@ -70,7 +70,7 @@ impl Accessor for Backend { let mut am: AccessorInfo = self.kv.metadata().into(); am.set_root(&self.root); - let cap = am.capability_mut(); + let cap = am.full_capability_mut(); if cap.read { cap.read_can_seek = true; cap.read_can_next = true; diff --git a/core/src/raw/adapters/typed_kv/backend.rs b/core/src/raw/adapters/typed_kv/backend.rs index af91d9042b8..b4353027495 100644 --- a/core/src/raw/adapters/typed_kv/backend.rs +++ b/core/src/raw/adapters/typed_kv/backend.rs @@ -69,7 +69,7 @@ impl Accessor for Backend { am.set_scheme(kv_info.scheme()); am.set_name(kv_info.name()); let kv_cap = kv_info.capabilities(); - let cap = am.capability_mut(); + let cap = am.full_capability_mut(); if kv_cap.get { cap.read = true; cap.read_can_seek = true; diff --git a/core/src/raw/oio/page/into_flat_page.rs b/core/src/raw/oio/page/into_flat_page.rs index 1f2ffb992d0..5699b14d783 100644 --- a/core/src/raw/oio/page/into_flat_page.rs +++ b/core/src/raw/oio/page/into_flat_page.rs @@ -29,7 +29,7 @@ pub fn into_flat_page(acc: A, path: &str, size: usize) -> FlatPa { let meta = acc.info(); debug_assert!( - meta.capability().list_with_delimiter_slash, + meta.full_capability().list_with_delimiter_slash, "service doesn't support list hierarchy, it must be a bug" ); } @@ -254,8 +254,8 @@ mod tests { fn info(&self) -> AccessorInfo { let mut am = AccessorInfo::default(); - am.capability_mut().list = true; - am.capability_mut().list_with_delimiter_slash = true; + am.full_capability_mut().list = true; + am.full_capability_mut().list_with_delimiter_slash = true; am } diff --git a/core/src/raw/oio/read/into_seekable_read_by_range.rs b/core/src/raw/oio/read/into_seekable_read_by_range.rs index b996c61e9f8..18fd8a33bbd 100644 --- a/core/src/raw/oio/read/into_seekable_read_by_range.rs +++ b/core/src/raw/oio/read/into_seekable_read_by_range.rs @@ -421,7 +421,7 @@ mod tests { fn info(&self) -> AccessorInfo { let mut am = AccessorInfo::default(); - am.set_capability(Capability { + am.set_full_capability(Capability { read: true, ..Default::default() }); diff --git a/core/src/services/azblob/backend.rs b/core/src/services/azblob/backend.rs index b635f02035e..5ec983cb760 100644 --- a/core/src/services/azblob/backend.rs +++ b/core/src/services/azblob/backend.rs @@ -518,7 +518,7 @@ impl Accessor for AzblobBackend { am.set_scheme(Scheme::Azblob) .set_root(&self.core.root) .set_name(&self.core.container) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, stat_with_if_match: true, stat_with_if_none_match: true, diff --git a/core/src/services/azdfs/backend.rs b/core/src/services/azdfs/backend.rs index b629894a2bd..5320a308951 100644 --- a/core/src/services/azdfs/backend.rs +++ b/core/src/services/azdfs/backend.rs @@ -241,7 +241,7 @@ impl Accessor for AzdfsBackend { am.set_scheme(Scheme::Azdfs) .set_root(&self.core.root) .set_name(&self.core.filesystem) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/cos/backend.rs b/core/src/services/cos/backend.rs index 78236f2f661..1ec1caccb63 100644 --- a/core/src/services/cos/backend.rs +++ b/core/src/services/cos/backend.rs @@ -279,7 +279,7 @@ impl Accessor for CosBackend { am.set_scheme(Scheme::Cos) .set_root(&self.core.root) .set_name(&self.core.bucket) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, stat_with_if_match: true, stat_with_if_none_match: true, diff --git a/core/src/services/dropbox/backend.rs b/core/src/services/dropbox/backend.rs index 642d22801be..29b4f12acda 100644 --- a/core/src/services/dropbox/backend.rs +++ b/core/src/services/dropbox/backend.rs @@ -59,7 +59,7 @@ impl Accessor for DropboxBackend { let mut ma = AccessorInfo::default(); ma.set_scheme(Scheme::Dropbox) .set_root(&self.core.root) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/fs/backend.rs b/core/src/services/fs/backend.rs index 53da83e50da..632e9fff400 100644 --- a/core/src/services/fs/backend.rs +++ b/core/src/services/fs/backend.rs @@ -256,7 +256,7 @@ impl Accessor for FsBackend { let mut am = AccessorInfo::default(); am.set_scheme(Scheme::Fs) .set_root(&self.root.to_string_lossy()) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/ftp/backend.rs b/core/src/services/ftp/backend.rs index b4067305fa2..2e643d35ffc 100644 --- a/core/src/services/ftp/backend.rs +++ b/core/src/services/ftp/backend.rs @@ -274,7 +274,7 @@ impl Accessor for FtpBackend { let mut am = AccessorInfo::default(); am.set_scheme(Scheme::Ftp) .set_root(&self.root) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index 20e605099fb..db0318a26fd 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -404,7 +404,7 @@ impl Accessor for GcsBackend { am.set_scheme(Scheme::Gcs) .set_root(&self.core.root) .set_name(&self.core.bucket) - .set_capability(Capability { + .set_full_capability(Capability { create_dir: true, stat: true, diff --git a/core/src/services/gdrive/backend.rs b/core/src/services/gdrive/backend.rs index 07e52a4d9f1..2aa1c4246b6 100644 --- a/core/src/services/gdrive/backend.rs +++ b/core/src/services/gdrive/backend.rs @@ -62,7 +62,7 @@ impl Accessor for GdriveBackend { let mut ma = AccessorInfo::default(); ma.set_scheme(crate::Scheme::Gdrive) .set_root(&self.core.root) - .set_capability(Capability { + .set_full_capability(Capability { read: true, write: true, delete: true, diff --git a/core/src/services/ghac/backend.rs b/core/src/services/ghac/backend.rs index 7197cee2ac4..db24d063ad2 100644 --- a/core/src/services/ghac/backend.rs +++ b/core/src/services/ghac/backend.rs @@ -304,7 +304,7 @@ impl Accessor for GhacBackend { am.set_scheme(Scheme::Ghac) .set_root(&self.root) .set_name(&self.version) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/hdfs/backend.rs b/core/src/services/hdfs/backend.rs index 0a6a255fbbf..1e28b68d8bf 100644 --- a/core/src/services/hdfs/backend.rs +++ b/core/src/services/hdfs/backend.rs @@ -173,7 +173,7 @@ impl Accessor for HdfsBackend { let mut am = AccessorInfo::default(); am.set_scheme(Scheme::Hdfs) .set_root(&self.root) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/http/backend.rs b/core/src/services/http/backend.rs index ec0e722d110..9135e723de1 100644 --- a/core/src/services/http/backend.rs +++ b/core/src/services/http/backend.rs @@ -263,7 +263,7 @@ impl Accessor for HttpBackend { let mut ma = AccessorInfo::default(); ma.set_scheme(Scheme::Http) .set_root(&self.root) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, stat_with_if_match: true, stat_with_if_none_match: true, diff --git a/core/src/services/ipfs/backend.rs b/core/src/services/ipfs/backend.rs index 32ee1d0b36e..2a1e0b09a1d 100644 --- a/core/src/services/ipfs/backend.rs +++ b/core/src/services/ipfs/backend.rs @@ -173,7 +173,7 @@ impl Accessor for IpfsBackend { let mut ma = AccessorInfo::default(); ma.set_scheme(Scheme::Ipfs) .set_root(&self.root) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/ipmfs/backend.rs b/core/src/services/ipmfs/backend.rs index 8dd05e6fb81..5d92d20f7d7 100644 --- a/core/src/services/ipmfs/backend.rs +++ b/core/src/services/ipmfs/backend.rs @@ -75,7 +75,7 @@ impl Accessor for IpmfsBackend { let mut am = AccessorInfo::default(); am.set_scheme(Scheme::Ipmfs) .set_root(&self.root) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/obs/backend.rs b/core/src/services/obs/backend.rs index 7a5aa96b775..56957a899ba 100644 --- a/core/src/services/obs/backend.rs +++ b/core/src/services/obs/backend.rs @@ -342,7 +342,7 @@ impl Accessor for ObsBackend { am.set_scheme(Scheme::Obs) .set_root(&self.core.root) .set_name(&self.core.bucket) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, stat_with_if_match: true, stat_with_if_none_match: true, diff --git a/core/src/services/onedrive/backend.rs b/core/src/services/onedrive/backend.rs index 3c55a07a2f2..236dae03b18 100644 --- a/core/src/services/onedrive/backend.rs +++ b/core/src/services/onedrive/backend.rs @@ -74,7 +74,7 @@ impl Accessor for OnedriveBackend { let mut ma = AccessorInfo::default(); ma.set_scheme(Scheme::Onedrive) .set_root(&self.root) - .set_capability(Capability { + .set_full_capability(Capability { read: true, write: true, stat: true, diff --git a/core/src/services/oss/backend.rs b/core/src/services/oss/backend.rs index 14cc08c2f93..65156ccc393 100644 --- a/core/src/services/oss/backend.rs +++ b/core/src/services/oss/backend.rs @@ -397,7 +397,7 @@ impl Accessor for OssBackend { am.set_scheme(Scheme::Oss) .set_root(&self.core.root) .set_name(&self.core.bucket) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, stat_with_if_match: true, stat_with_if_none_match: true, diff --git a/core/src/services/s3/backend.rs b/core/src/services/s3/backend.rs index 0a2babb5347..54220b71144 100644 --- a/core/src/services/s3/backend.rs +++ b/core/src/services/s3/backend.rs @@ -902,7 +902,7 @@ impl Accessor for S3Backend { am.set_scheme(Scheme::S3) .set_root(&self.core.root) .set_name(&self.core.bucket) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, stat_with_if_match: true, stat_with_if_none_match: true, diff --git a/core/src/services/sftp/backend.rs b/core/src/services/sftp/backend.rs index 4cb68f95ad5..425568d1384 100644 --- a/core/src/services/sftp/backend.rs +++ b/core/src/services/sftp/backend.rs @@ -233,7 +233,7 @@ impl Accessor for SftpBackend { let mut am = AccessorInfo::default(); am.set_root(self.root.as_str()) .set_scheme(Scheme::Sftp) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/supabase/backend.rs b/core/src/services/supabase/backend.rs index a893ecc50e6..18ef035e846 100644 --- a/core/src/services/supabase/backend.rs +++ b/core/src/services/supabase/backend.rs @@ -218,7 +218,7 @@ impl Accessor for SupabaseBackend { am.set_scheme(Scheme::Supabase) .set_root(&self.core.root) .set_name(&self.core.bucket) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/vercel_artifacts/backend.rs b/core/src/services/vercel_artifacts/backend.rs index b8a9d649162..866cb28cd33 100644 --- a/core/src/services/vercel_artifacts/backend.rs +++ b/core/src/services/vercel_artifacts/backend.rs @@ -55,7 +55,7 @@ impl Accessor for VercelArtifactsBackend { fn info(&self) -> AccessorInfo { let mut ma = AccessorInfo::default(); ma.set_scheme(Scheme::VercelArtifacts) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/wasabi/backend.rs b/core/src/services/wasabi/backend.rs index 954eec8f6b0..7aabc55c44d 100644 --- a/core/src/services/wasabi/backend.rs +++ b/core/src/services/wasabi/backend.rs @@ -902,7 +902,7 @@ impl Accessor for WasabiBackend { am.set_scheme(Scheme::Wasabi) .set_root(&self.core.root) .set_name(&self.core.bucket) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, stat_with_if_match: true, stat_with_if_none_match: true, diff --git a/core/src/services/webdav/backend.rs b/core/src/services/webdav/backend.rs index 49b1e981d9a..d472153fabf 100644 --- a/core/src/services/webdav/backend.rs +++ b/core/src/services/webdav/backend.rs @@ -282,7 +282,7 @@ impl Accessor for WebdavBackend { let mut ma = AccessorInfo::default(); ma.set_scheme(Scheme::Webdav) .set_root(&self.root) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/services/webhdfs/backend.rs b/core/src/services/webhdfs/backend.rs index 7bbe6c7c929..a8a17f0689a 100644 --- a/core/src/services/webhdfs/backend.rs +++ b/core/src/services/webhdfs/backend.rs @@ -409,7 +409,7 @@ impl Accessor for WebhdfsBackend { let mut am = AccessorInfo::default(); am.set_scheme(Scheme::Webhdfs) .set_root(&self.root) - .set_capability(Capability { + .set_full_capability(Capability { stat: true, read: true, diff --git a/core/src/types/operator/blocking_operator.rs b/core/src/types/operator/blocking_operator.rs index ade1086da34..0650d2ba8ab 100644 --- a/core/src/types/operator/blocking_operator.rs +++ b/core/src/types/operator/blocking_operator.rs @@ -71,7 +71,7 @@ impl BlockingOperator { pub(crate) fn from_inner(accessor: FusedAccessor) -> Self { let limit = accessor .info() - .capability() + .full_capability() .batch_max_operations .unwrap_or(1000); Self { accessor, limit } diff --git a/core/src/types/operator/metadata.rs b/core/src/types/operator/metadata.rs index 3d219dfca44..397b5ef7e7e 100644 --- a/core/src/types/operator/metadata.rs +++ b/core/src/types/operator/metadata.rs @@ -47,53 +47,13 @@ impl OperatorInfo { self.0.name() } - /// Get [`Capability`] of operator. - pub fn capability(&self) -> Capability { - self.0.capability() + /// Get [`Full Capability`] of operator. + pub fn full_capability(&self) -> Capability { + self.0.full_capability() } - /// Check if current backend supports [`Accessor::read`] or not. - pub fn can_read(&self) -> bool { - self.0.capability().read - } - - /// Check if current backend supports [`Accessor::write`] or not. - pub fn can_write(&self) -> bool { - self.0.capability().write - } - - /// Check if current backend supports [`Accessor::append`] or not. - pub fn can_append(&self) -> bool { - self.0.capability().append - } - - /// Check if current backend supports [`Accessor::copy`] or not. - pub fn can_copy(&self) -> bool { - self.0.capability().copy - } - - /// Check if current backend supports [`Accessor::rename`] or not. - pub fn can_rename(&self) -> bool { - self.0.capability().rename - } - - /// Check if current backend supports [`Accessor::list`] or not. - pub fn can_list(&self) -> bool { - self.0.capability().list - } - - /// Check if current backend supports [`Accessor::presign`] or not. - pub fn can_presign(&self) -> bool { - self.0.capability().presign - } - - /// Check if current backend supports batch operations or not. - pub fn can_batch(&self) -> bool { - self.0.capability().batch - } - - /// Check if current backend supports blocking operations or not. - pub fn can_blocking(&self) -> bool { - self.0.capability().blocking + /// Get [`Native Capability`] of operator. + pub fn native_capability(&self) -> Capability { + self.0.native_capability() } } diff --git a/core/src/types/operator/operator.rs b/core/src/types/operator/operator.rs index 92959e726db..9df7c7bbe42 100644 --- a/core/src/types/operator/operator.rs +++ b/core/src/types/operator/operator.rs @@ -80,7 +80,7 @@ impl Operator { pub(crate) fn from_inner(accessor: FusedAccessor) -> Self { let limit = accessor .info() - .capability() + .full_capability() .batch_max_operations .unwrap_or(1000); Self { accessor, limit } @@ -1059,7 +1059,7 @@ impl Operator { /// # } /// ``` pub async fn remove_via(&self, input: impl Stream + Unpin) -> Result<()> { - if self.info().can_batch() { + if self.info().full_capability().batch { let mut input = input .map(|v| (v, OpDelete::default().into())) .chunks(self.limit()); @@ -1127,7 +1127,7 @@ impl Operator { let obs = self.lister_with(path).delimiter("").await?; - if self.info().can_batch() { + if self.info().full_capability().batch { let mut obs = obs.try_chunks(self.limit()); while let Some(batches) = obs.next().await { diff --git a/core/tests/behavior/append.rs b/core/tests/behavior/append.rs index 0e5cf8801b7..782a323c52b 100644 --- a/core/tests/behavior/append.rs +++ b/core/tests/behavior/append.rs @@ -27,7 +27,7 @@ use sha2::Sha256; use crate::*; pub fn behavior_append_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && cap.write && cap.append) { return vec![]; @@ -84,7 +84,7 @@ pub async fn test_append_with_dir_path(op: Operator) -> Result<()> { /// Test append with cache control must success. pub async fn test_append_with_cache_control(op: Operator) -> Result<()> { - if !op.info().capability().append_with_cache_control { + if !op.info().full_capability().append_with_cache_control { return Ok(()); } @@ -110,7 +110,7 @@ pub async fn test_append_with_cache_control(op: Operator) -> Result<()> { /// Test append with content type must success. pub async fn test_append_with_content_type(op: Operator) -> Result<()> { - if !op.info().capability().append_with_content_type { + if !op.info().full_capability().append_with_content_type { return Ok(()); } @@ -137,7 +137,7 @@ pub async fn test_append_with_content_type(op: Operator) -> Result<()> { /// Write a single file with content disposition should succeed. pub async fn test_append_with_content_disposition(op: Operator) -> Result<()> { - if !op.info().capability().append_with_content_disposition { + if !op.info().full_capability().append_with_content_disposition { return Ok(()); } diff --git a/core/tests/behavior/blocking_copy.rs b/core/tests/behavior/blocking_copy.rs index 43d0faec5ce..822369a229f 100644 --- a/core/tests/behavior/blocking_copy.rs +++ b/core/tests/behavior/blocking_copy.rs @@ -20,7 +20,7 @@ use anyhow::Result; use crate::*; pub fn behavior_blocking_copy_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && cap.write && cap.copy && cap.blocking) { return vec![]; diff --git a/core/tests/behavior/blocking_list.rs b/core/tests/behavior/blocking_list.rs index 2f6e9e534b7..96f60bab10d 100644 --- a/core/tests/behavior/blocking_list.rs +++ b/core/tests/behavior/blocking_list.rs @@ -24,7 +24,7 @@ use log::debug; use crate::*; pub fn behavior_blocking_list_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && cap.write && cap.copy && cap.blocking && cap.list) { return vec![]; diff --git a/core/tests/behavior/blocking_read_only.rs b/core/tests/behavior/blocking_read_only.rs index 847fa63e4d5..6c4f5e0ab29 100644 --- a/core/tests/behavior/blocking_read_only.rs +++ b/core/tests/behavior/blocking_read_only.rs @@ -22,7 +22,7 @@ use sha2::Sha256; use crate::*; pub fn behavior_blocking_read_only_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && !cap.write && cap.blocking) { return vec![]; diff --git a/core/tests/behavior/blocking_rename.rs b/core/tests/behavior/blocking_rename.rs index 4506c2c5c0e..398a3f4daca 100644 --- a/core/tests/behavior/blocking_rename.rs +++ b/core/tests/behavior/blocking_rename.rs @@ -20,7 +20,7 @@ use anyhow::Result; use crate::*; pub fn behavior_blocking_rename_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && cap.write && cap.copy && cap.blocking && cap.rename) { return vec![]; diff --git a/core/tests/behavior/blocking_write.rs b/core/tests/behavior/blocking_write.rs index 2b4f65a9170..06d44a1b90b 100644 --- a/core/tests/behavior/blocking_write.rs +++ b/core/tests/behavior/blocking_write.rs @@ -27,7 +27,7 @@ use sha2::Sha256; use crate::*; pub fn behavior_blocking_write_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && cap.write && cap.blocking) { return vec![]; @@ -217,7 +217,7 @@ pub fn test_blocking_read_full(op: BlockingOperator) -> Result<()> { /// Read range content should match. pub fn test_blocking_read_range(op: BlockingOperator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -246,7 +246,7 @@ pub fn test_blocking_read_range(op: BlockingOperator) -> Result<()> { /// Read large range content should match. pub fn test_blocking_read_large_range(op: BlockingOperator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -286,7 +286,7 @@ pub fn test_blocking_read_not_exist(op: BlockingOperator) -> Result<()> { } pub fn test_blocking_fuzz_range_reader(op: BlockingOperator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -323,7 +323,7 @@ pub fn test_blocking_fuzz_range_reader(op: BlockingOperator) -> Result<()> { } pub fn test_blocking_fuzz_offset_reader(op: BlockingOperator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -360,7 +360,7 @@ pub fn test_blocking_fuzz_offset_reader(op: BlockingOperator) -> Result<()> { } pub fn test_blocking_fuzz_part_reader(op: BlockingOperator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } diff --git a/core/tests/behavior/copy.rs b/core/tests/behavior/copy.rs index 086fa160ecf..0e9353d9551 100644 --- a/core/tests/behavior/copy.rs +++ b/core/tests/behavior/copy.rs @@ -20,7 +20,7 @@ use anyhow::Result; use crate::*; pub fn behavior_copy_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && cap.write && cap.copy) { return vec![]; diff --git a/core/tests/behavior/fuzz.rs b/core/tests/behavior/fuzz.rs index cca74763b41..8a7b8187feb 100644 --- a/core/tests/behavior/fuzz.rs +++ b/core/tests/behavior/fuzz.rs @@ -67,7 +67,7 @@ pub fn behavior_fuzz_tests(op: &Operator) -> Vec { /// is invalid for given range `1..2`. However, the actual behavior is we seek to `0` /// and results in a panic. pub async fn test_fuzz_issue_2717(op: Operator) -> Result<()> { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && cap.write & cap.read_with_range) { return Ok(()); diff --git a/core/tests/behavior/list.rs b/core/tests/behavior/list.rs index 79a36fe8743..071c8dbc468 100644 --- a/core/tests/behavior/list.rs +++ b/core/tests/behavior/list.rs @@ -27,7 +27,7 @@ use log::debug; use crate::*; pub fn behavior_list_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && cap.write && cap.list) { return vec![]; @@ -335,7 +335,7 @@ pub async fn test_list_dir_with_file_path(op: Operator) -> Result<()> { /// List with start after should start listing after the specified key pub async fn test_list_with_start_after(op: Operator) -> Result<()> { - if !op.info().capability().list_with_start_after { + if !op.info().full_capability().list_with_start_after { return Ok(()); } diff --git a/core/tests/behavior/list_only.rs b/core/tests/behavior/list_only.rs index e7778461d0d..27de2a743e8 100644 --- a/core/tests/behavior/list_only.rs +++ b/core/tests/behavior/list_only.rs @@ -23,7 +23,7 @@ use futures::TryStreamExt; use crate::*; pub fn behavior_list_only_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !cap.list || cap.write { return vec![]; diff --git a/core/tests/behavior/presign.rs b/core/tests/behavior/presign.rs index 8e2b2d2f2b6..7ddc9082bf4 100644 --- a/core/tests/behavior/presign.rs +++ b/core/tests/behavior/presign.rs @@ -29,7 +29,7 @@ use sha2::Sha256; use crate::*; pub fn behavior_presign_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.list && cap.write && cap.presign) { return vec![]; diff --git a/core/tests/behavior/read_only.rs b/core/tests/behavior/read_only.rs index 5037e4426e0..85d897aafca 100644 --- a/core/tests/behavior/read_only.rs +++ b/core/tests/behavior/read_only.rs @@ -23,7 +23,7 @@ use sha2::Sha256; use crate::*; pub fn behavior_read_only_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !cap.read || cap.write { return vec![]; @@ -97,7 +97,7 @@ pub async fn test_read_only_stat_not_exist(op: Operator) -> Result<()> { /// Stat with if_match should succeed, else get a ConditionNotMatch error. pub async fn test_read_only_stat_with_if_match(op: Operator) -> Result<()> { - if !op.info().capability().stat_with_if_match { + if !op.info().full_capability().stat_with_if_match { return Ok(()); } @@ -122,7 +122,7 @@ pub async fn test_read_only_stat_with_if_match(op: Operator) -> Result<()> { /// Stat with if_none_match should succeed, else get a ConditionNotMatch. pub async fn test_read_only_stat_with_if_none_match(op: Operator) -> Result<()> { - if !op.info().capability().stat_with_if_none_match { + if !op.info().full_capability().stat_with_if_none_match { return Ok(()); } @@ -271,7 +271,7 @@ pub async fn test_read_only_read_with_dir_path(op: Operator) -> Result<()> { /// Read with if_match should match, else get a ConditionNotMatch error. pub async fn test_read_only_read_with_if_match(op: Operator) -> Result<()> { - if !op.info().capability().read_with_if_match { + if !op.info().full_capability().read_with_if_match { return Ok(()); } @@ -300,7 +300,7 @@ pub async fn test_read_only_read_with_if_match(op: Operator) -> Result<()> { /// Read with if_none_match should match, else get a ConditionNotMatch error. pub async fn test_read_only_read_with_if_none_match(op: Operator) -> Result<()> { - if !op.info().capability().read_with_if_none_match { + if !op.info().full_capability().read_with_if_none_match { return Ok(()); } diff --git a/core/tests/behavior/rename.rs b/core/tests/behavior/rename.rs index d6c64a80548..ac4974c8f40 100644 --- a/core/tests/behavior/rename.rs +++ b/core/tests/behavior/rename.rs @@ -20,7 +20,7 @@ use anyhow::Result; use crate::*; pub fn behavior_rename_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && cap.write && cap.rename) { return vec![]; diff --git a/core/tests/behavior/write.rs b/core/tests/behavior/write.rs index 53ee845813f..590ae6c067f 100644 --- a/core/tests/behavior/write.rs +++ b/core/tests/behavior/write.rs @@ -35,7 +35,7 @@ use sha2::Sha256; use crate::*; pub fn behavior_write_tests(op: &Operator) -> Vec { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.read && cap.write) { return vec![]; @@ -168,7 +168,7 @@ pub async fn test_write_with_special_chars(op: Operator) -> Result<()> { /// Write a single file with cache control should succeed. pub async fn test_write_with_cache_control(op: Operator) -> Result<()> { - if !op.info().capability().write_with_cache_control { + if !op.info().full_capability().write_with_cache_control { return Ok(()); } @@ -194,7 +194,7 @@ pub async fn test_write_with_cache_control(op: Operator) -> Result<()> { /// Write a single file with content type should succeed. pub async fn test_write_with_content_type(op: Operator) -> Result<()> { - if !op.info().capability().write_with_content_type { + if !op.info().full_capability().write_with_content_type { return Ok(()); } @@ -221,7 +221,7 @@ pub async fn test_write_with_content_type(op: Operator) -> Result<()> { /// Write a single file with content disposition should succeed. pub async fn test_write_with_content_disposition(op: Operator) -> Result<()> { - if !op.info().capability().write_with_content_disposition { + if !op.info().full_capability().write_with_content_disposition { return Ok(()); } @@ -324,7 +324,7 @@ pub async fn test_stat_not_exist(op: Operator) -> Result<()> { /// Stat with if_match should succeed, else get a ConditionNotMatch error. pub async fn test_stat_with_if_match(op: Operator) -> Result<()> { - if !op.info().capability().stat_with_if_match { + if !op.info().full_capability().stat_with_if_match { return Ok(()); } @@ -356,7 +356,7 @@ pub async fn test_stat_with_if_match(op: Operator) -> Result<()> { /// Stat with if_none_match should succeed, else get a ConditionNotMatch. pub async fn test_stat_with_if_none_match(op: Operator) -> Result<()> { - if !op.info().capability().stat_with_if_none_match { + if !op.info().full_capability().stat_with_if_none_match { return Ok(()); } @@ -425,7 +425,7 @@ pub async fn test_read_full(op: Operator) -> Result<()> { /// Read range content should match. pub async fn test_read_range(op: Operator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -455,7 +455,7 @@ pub async fn test_read_range(op: Operator) -> Result<()> { /// Read large range content should match. pub async fn test_read_large_range(op: Operator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -486,7 +486,7 @@ pub async fn test_read_large_range(op: Operator) -> Result<()> { /// Read range content should match. pub async fn test_reader_range(op: Operator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -519,7 +519,7 @@ pub async fn test_reader_range(op: Operator) -> Result<()> { /// Read range from should match. pub async fn test_reader_from(op: Operator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -550,7 +550,7 @@ pub async fn test_reader_from(op: Operator) -> Result<()> { /// Read range tail should match. pub async fn test_reader_tail(op: Operator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -600,7 +600,7 @@ pub async fn test_read_not_exist(op: Operator) -> Result<()> { /// Read with if_match should match, else get a ConditionNotMatch error. pub async fn test_read_with_if_match(op: Operator) -> Result<()> { - if !op.info().capability().read_with_if_match { + if !op.info().full_capability().read_with_if_match { return Ok(()); } @@ -631,7 +631,7 @@ pub async fn test_read_with_if_match(op: Operator) -> Result<()> { /// Read with if_none_match should match, else get a ConditionNotMatch error. pub async fn test_read_with_if_none_match(op: Operator) -> Result<()> { - if !op.info().capability().read_with_if_none_match { + if !op.info().full_capability().read_with_if_none_match { return Ok(()); } @@ -664,7 +664,7 @@ pub async fn test_read_with_if_none_match(op: Operator) -> Result<()> { } pub async fn test_fuzz_range_reader(op: Operator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -705,7 +705,7 @@ pub async fn test_fuzz_range_reader(op: Operator) -> Result<()> { } pub async fn test_fuzz_offset_reader(op: Operator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -746,7 +746,7 @@ pub async fn test_fuzz_offset_reader(op: Operator) -> Result<()> { } pub async fn test_fuzz_part_reader(op: Operator) -> Result<()> { - if !op.info().capability().read_with_range { + if !op.info().full_capability().read_with_range { return Ok(()); } @@ -832,7 +832,9 @@ pub async fn test_read_with_special_chars(op: Operator) -> Result<()> { /// Read file with override-cache-control should succeed. pub async fn test_read_with_override_cache_control(op: Operator) -> Result<()> { - if !(op.info().capability().read_with_override_cache_control && op.info().can_presign()) { + if !(op.info().full_capability().read_with_override_cache_control + && op.info().full_capability().presign) + { return Ok(()); } @@ -879,9 +881,9 @@ pub async fn test_read_with_override_cache_control(op: Operator) -> Result<()> { pub async fn test_read_with_override_content_disposition(op: Operator) -> Result<()> { if !(op .info() - .capability() + .full_capability() .read_with_override_content_disposition - && op.info().can_presign()) + && op.info().full_capability().presign) { return Ok(()); } @@ -930,7 +932,9 @@ pub async fn test_read_with_override_content_disposition(op: Operator) -> Result /// Read file with override_content_type should succeed. pub async fn test_read_with_override_content_type(op: Operator) -> Result<()> { - if !(op.info().capability().read_with_override_content_type && op.info().can_presign()) { + if !(op.info().full_capability().read_with_override_content_type + && op.info().full_capability().presign) + { return Ok(()); } @@ -1144,7 +1148,7 @@ pub async fn test_writer_write(op: Operator) -> Result<()> { /// Streaming data into writer pub async fn test_writer_sink(op: Operator) -> Result<()> { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.write && cap.write_can_sink) { return Ok(()); } @@ -1184,7 +1188,7 @@ pub async fn test_writer_sink(op: Operator) -> Result<()> { /// Reading data into writer pub async fn test_writer_copy(op: Operator) -> Result<()> { - let cap = op.info().capability(); + let cap = op.info().full_capability(); if !(cap.write && cap.write_can_sink) { return Ok(()); } @@ -1259,7 +1263,7 @@ pub async fn test_writer_futures_copy(op: Operator) -> Result<()> { /// Add test for unsized writer pub async fn test_fuzz_unsized_writer(op: Operator) -> Result<()> { - if !op.info().capability().write_without_content_length { + if !op.info().full_capability().write_without_content_length { warn!("{op:?} doesn't support write without content length, test skip"); return Ok(()); }