rustfs_rsc/client/
bucket.rs

1use std::path::Path;
2use std::pin::Pin;
3
4use bytes::Bytes;
5use futures_core::Stream;
6use hyper::Method;
7use reqwest::Response;
8
9use super::{BucketArgs, CopySource, KeyArgs, ListObjectsArgs, ObjectLockConfig, Tags};
10use super::{ObjectStat, SelectObjectReader};
11use crate::datatype::{
12    AccessControlPolicy, CORSConfiguration, ListBucketResult, PublicAccessBlockConfiguration, Retention
13};
14use crate::datatype::{SelectRequest, ServerSideEncryptionConfiguration};
15use crate::{error::Result, Minio};
16
17/// Instantiate an Bucket which wrap [Minio] and [BucketArgs].
18/// Provides operations on objects.
19#[derive(Clone)]
20pub struct Bucket {
21    pub(super) client: Minio,
22    pub(super) bucket: BucketArgs,
23}
24
25macro_rules! proxy_object {
26    ($name:ident, $reponse:ty $(,$an:ident=>$at:ty)*) => {
27        #[inline]
28        pub async fn $name<K>(&self, key: K, $($an:$at),*) -> Result<$reponse>
29        where
30            K: Into<KeyArgs>,
31        {
32            self.client
33                .$name(self.bucket.clone(), key, $($an),*)
34                .await
35        }
36    };
37}
38
39macro_rules! proxy_bucket {
40    ($name:ident=>$name2:ident, $reponse:ty) => {
41        #[inline]
42        pub async fn $name2(&self) -> Result<$reponse> {
43            self.client.$name(self.bucket.clone()).await
44        }
45    };
46
47    ($name:ident=>$name2:ident, $reponse:ty, $args:ty) => {
48        #[inline]
49        pub async fn $name2(&self, args: $args) -> Result<$reponse> {
50            self.client.$name(self.bucket.clone(), args).await
51        }
52    };
53
54    ($name:ident, $reponse:ty) => {
55        #[inline]
56        pub async fn $name(&self) -> Result<$reponse> {
57            self.client.$name(self.bucket.clone()).await
58        }
59    };
60
61    ($name:ident, $reponse:ty, $args:ty) => {
62        #[inline]
63        pub async fn $name(&self, args: $args) -> Result<$reponse> {
64            self.client.$name(self.bucket.clone(), args).await
65        }
66    };
67}
68
69type FsStream = Pin<Box<dyn Stream<Item = Result<Bytes>> + Sync + Send>>;
70
71impl Bucket {
72    #[inline]
73    pub fn bucket_args(&self) -> BucketArgs {
74        self.bucket.clone()
75    }
76
77    /// Check if exists.
78    /// If exists and you have permission to access it, return [Ok(true)], otherwise [Ok(false)]
79    pub async fn exists(&self) -> Result<bool> {
80        let bucket: BucketArgs = self.bucket.clone();
81        self.client
82            ._bucket_executor(bucket, Method::HEAD)
83            .send()
84            .await
85            .map(|res| res.status().is_success())
86    }
87
88    proxy_bucket!(list_objects, ListBucketResult, ListObjectsArgs);
89    proxy_bucket!(get_bucket_acl=>get_acl, AccessControlPolicy);
90    proxy_bucket!(get_bucket_region=>get_region, String);
91
92    proxy_bucket!(get_bucket_cors=>get_cors, CORSConfiguration);
93    proxy_bucket!(set_bucket_cors=>set_cors, (),CORSConfiguration);
94    proxy_bucket!(del_bucket_cors=>del_cors,());
95
96    proxy_bucket!(get_bucket_encryption=>get_encryption, ServerSideEncryptionConfiguration);
97    proxy_bucket!(set_bucket_encryption=>set_encryption, (),ServerSideEncryptionConfiguration);
98    proxy_bucket!(del_bucket_encryption=>del_encryption,());
99
100    proxy_bucket!(get_public_access_block, PublicAccessBlockConfiguration);
101    proxy_bucket!(set_public_access_block, (), PublicAccessBlockConfiguration);
102    proxy_bucket!(del_public_access_block, ());
103
104    proxy_bucket!(get_bucket_tags=>get_tags, Option<Tags>);
105    proxy_bucket!(set_bucket_tags=>set_tags, (),Tags);
106    proxy_bucket!(del_bucket_tags=>del_tags,());
107
108    proxy_bucket!(del_object_lock_config, ());
109    proxy_bucket!(get_object_lock_config, ObjectLockConfig);
110    proxy_bucket!(set_object_lock_config, (), ObjectLockConfig);
111
112    proxy_object!(get_object, Response);
113    proxy_object!(get_object_torrent, Response);
114    proxy_object!(put_object, (), data=>Bytes);
115    proxy_object!(put_object_stream, (), stream=>FsStream, len=>Option<usize>);
116    proxy_object!(copy_object, (), cp=> CopySource);
117    proxy_object!(remove_object, ());
118    proxy_object!(stat_object, Option<ObjectStat>);
119    proxy_object!(is_object_legal_hold_enabled, bool);
120    proxy_object!(enable_object_legal_hold_enabled, ());
121    proxy_object!(disable_object_legal_hold_enabled, ());
122    proxy_object!(get_object_tags, Tags);
123    proxy_object!(set_object_tags, (), tags=>Tags);
124    proxy_object!(del_object_tags, ());
125    proxy_object!(get_object_retention, Retention);
126    proxy_object!(set_object_retention, (), retention=>Retention);
127    proxy_object!(select_object_content, SelectObjectReader, request=>SelectRequest);
128    proxy_object!(get_object_acl, AccessControlPolicy);
129
130    #[cfg(feature = "fs-tokio")]
131    #[inline]
132    pub async fn fget_object<K, P>(&self, key: K, path: P) -> Result<()>
133    where
134        K: Into<KeyArgs>,
135        P: AsRef<Path>,
136    {
137        self.client
138            .fget_object(self.bucket.clone(), key, path)
139            .await
140    }
141
142    #[cfg(feature = "fs-tokio")]
143    #[inline]
144    pub async fn fput_object<K, P>(&self, key: K, path: P) -> Result<()>
145    where
146        K: Into<KeyArgs>,
147        P: AsRef<Path>,
148    {
149        self.client
150            .fput_object(self.bucket.clone(), key, path)
151            .await
152    }
153}
154
155impl Into<BucketArgs> for Bucket {
156    fn into(self) -> BucketArgs {
157        self.bucket
158    }
159}
160
161impl Into<BucketArgs> for &Bucket {
162    fn into(self) -> BucketArgs {
163        self.bucket.clone()
164    }
165}