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#[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 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}