toolcraft_s3_kit/minio/
s3.rs

1use minio::s3::{
2    client::{Client, ClientBuilder},
3    creds::StaticProvider,
4    http::BaseUrl,
5    types::S3Api,
6};
7
8use crate::error::{Error, Result};
9
10pub struct S3Client {
11    client: Client,
12}
13
14impl S3Client {
15    pub fn new(endpoint: &str, access_key: &str, secret_key: &str) -> Result<Self> {
16        let base_url = endpoint.parse::<BaseUrl>().map_err(|e| {
17            Error::ErrorMessage(Box::from(format!("failed to parse base url: {e}")))
18        })?;
19        let provider = StaticProvider::new(access_key, secret_key, None);
20
21        let client = ClientBuilder::new(base_url)
22            .provider(Some(Box::new(provider)))
23            .build()
24            .map_err(|e| {
25                Error::ErrorMessage(Box::from(format!("failed to build S3 client: {e}")))
26            })?;
27
28        Ok(S3Client { client })
29    }
30
31    pub async fn read_text_file(&self, bucket: &str, file_path: &str) -> Result<String> {
32        let get_object = self
33            .client
34            .get_object(bucket, file_path)
35            .send()
36            .await
37            .map_err(|e| Error::ErrorMessage(Box::from(format!("failed to get object: {e}"))))?;
38
39        // 从 ObjectContent 读取内容
40        let content = get_object.content;
41
42        // 使用 to_segmented_bytes() 方法读取所有内容
43        let segmented_bytes = content.to_segmented_bytes().await?;
44
45        // 将 SegmentedBytes 转换为 Vec<u8>
46        let mut buffer = Vec::new();
47        for chunk in segmented_bytes.into_iter() {
48            buffer.extend_from_slice(&chunk);
49        }
50
51        // 转换为字符串(仅适用于文本文件)
52        let text_content = String::from_utf8(buffer)?;
53
54        // println!("📄 文件内容: {}", text_content);
55        // println!("📊 文件大小: {} bytes", get_object.object_size);
56
57        // if let Some(etag) = get_object.etag {
58        //     println!("🏷️  ETag: {}", etag);
59        // }
60
61        Ok(text_content)
62    }
63}