use super::*; #[async_trait::async_trait] pub trait ObjectIO: Send + Sync + Debug + 'static { async fn get_object_reader( &self, bucket: &str, object: &str, range: Option, h: HeaderMap, opts: &ObjectOptions, ) -> Result; async fn put_object(&self, bucket: &str, object: &str, data: &mut PutObjReader, opts: &ObjectOptions) -> Result; } /// Bucket-level storage operations. #[async_trait::async_trait] pub trait BucketOperations: Send + Sync + Debug { async fn make_bucket(&self, bucket: &str, opts: &MakeBucketOptions) -> Result<()>; async fn get_bucket_info(&self, bucket: &str, opts: &BucketOptions) -> Result; async fn list_bucket(&self, opts: &BucketOptions) -> Result>; async fn delete_bucket(&self, bucket: &str, opts: &DeleteBucketOptions) -> Result<()>; } /// Object-level storage operations (beyond basic I/O in ObjectIO). #[async_trait::async_trait] #[allow(clippy::too_many_arguments)] pub trait ObjectOperations: Send + Sync + Debug { async fn get_object_info(&self, bucket: &str, object: &str, opts: &ObjectOptions) -> Result; async fn verify_object_integrity(&self, bucket: &str, object: &str, opts: &ObjectOptions) -> Result<()>; async fn copy_object( &self, src_bucket: &str, src_object: &str, dst_bucket: &str, dst_object: &str, src_info: &mut ObjectInfo, src_opts: &ObjectOptions, dst_opts: &ObjectOptions, ) -> Result; async fn delete_object_version(&self, bucket: &str, object: &str, fi: &FileInfo, force_del_marker: bool) -> Result<()>; async fn delete_object(&self, bucket: &str, object: &str, opts: ObjectOptions) -> Result; async fn delete_objects( &self, bucket: &str, objects: Vec, opts: ObjectOptions, ) -> (Vec, Vec>); async fn put_object_metadata(&self, bucket: &str, object: &str, opts: &ObjectOptions) -> Result; async fn get_object_tags(&self, bucket: &str, object: &str, opts: &ObjectOptions) -> Result; async fn put_object_tags(&self, bucket: &str, object: &str, tags: &str, opts: &ObjectOptions) -> Result; async fn delete_object_tags(&self, bucket: &str, object: &str, opts: &ObjectOptions) -> Result; async fn add_partial(&self, bucket: &str, object: &str, version_id: &str) -> Result<()>; async fn transition_object(&self, bucket: &str, object: &str, opts: &ObjectOptions) -> Result<()>; async fn restore_transitioned_object(self: Arc, bucket: &str, object: &str, opts: &ObjectOptions) -> Result<()>; } /// Listing and walking operations. #[async_trait::async_trait] #[allow(clippy::too_many_arguments)] pub trait ListOperations: Send + Sync + Debug { async fn list_objects_v2( self: Arc, bucket: &str, prefix: &str, continuation_token: Option, delimiter: Option, max_keys: i32, fetch_owner: bool, start_after: Option, incl_deleted: bool, ) -> Result; async fn list_object_versions( self: Arc, bucket: &str, prefix: &str, marker: Option, version_marker: Option, delimiter: Option, max_keys: i32, ) -> Result; async fn walk( self: Arc, rx: CancellationToken, bucket: &str, prefix: &str, result: tokio::sync::mpsc::Sender, opts: WalkOptions, ) -> Result<()>; } /// Multipart upload operations. #[async_trait::async_trait] #[allow(clippy::too_many_arguments)] pub trait MultipartOperations: Send + Sync + Debug { async fn list_multipart_uploads( &self, bucket: &str, prefix: &str, key_marker: Option, upload_id_marker: Option, delimiter: Option, max_uploads: usize, ) -> Result; async fn new_multipart_upload(&self, bucket: &str, object: &str, opts: &ObjectOptions) -> Result; async fn copy_object_part( &self, src_bucket: &str, src_object: &str, dst_bucket: &str, dst_object: &str, upload_id: &str, part_id: usize, start_offset: i64, length: i64, src_info: &ObjectInfo, src_opts: &ObjectOptions, dst_opts: &ObjectOptions, ) -> Result<()>; async fn put_object_part( &self, bucket: &str, object: &str, upload_id: &str, part_id: usize, data: &mut PutObjReader, opts: &ObjectOptions, ) -> Result; async fn get_multipart_info( &self, bucket: &str, object: &str, upload_id: &str, opts: &ObjectOptions, ) -> Result; async fn list_object_parts( &self, bucket: &str, object: &str, upload_id: &str, part_number_marker: Option, max_parts: usize, opts: &ObjectOptions, ) -> Result; async fn abort_multipart_upload(&self, bucket: &str, object: &str, upload_id: &str, opts: &ObjectOptions) -> Result<()>; async fn complete_multipart_upload( self: Arc, bucket: &str, object: &str, upload_id: &str, uploaded_parts: Vec, opts: &ObjectOptions, ) -> Result; } /// Healing and repair operations. #[async_trait::async_trait] pub trait HealOperations: Send + Sync + Debug { async fn heal_format(&self, dry_run: bool) -> Result<(HealResultItem, Option)>; async fn heal_bucket(&self, bucket: &str, opts: &HealOpts) -> Result; async fn heal_object( &self, bucket: &str, object: &str, version_id: &str, opts: &HealOpts, ) -> Result<(HealResultItem, Option)>; async fn get_pool_and_set(&self, id: &str) -> Result<(Option, Option, Option)>; async fn check_abandoned_parts(&self, bucket: &str, object: &str, opts: &HealOpts) -> Result<()>; } /// Unified storage API combining all operation groups. /// /// Consumers can depend on specific sub-traits (e.g., `BucketOperations`) /// when they don't need the full API surface. #[async_trait::async_trait] #[allow(clippy::too_many_arguments)] pub trait StorageAPI: ObjectIO + BucketOperations + ObjectOperations + ListOperations + MultipartOperations + HealOperations + Debug { async fn new_ns_lock(&self, bucket: &str, object: &str) -> Result; async fn backend_info(&self) -> rustfs_madmin::BackendInfo; async fn storage_info(&self) -> rustfs_madmin::StorageInfo; async fn local_storage_info(&self) -> rustfs_madmin::StorageInfo; async fn get_disks(&self, pool_idx: usize, set_idx: usize) -> Result>>; fn set_drive_counts(&self) -> Vec; }