aws_multipart_upload/client/
hashmap.rs

1use aws_sdk_s3::primitives::ByteStream;
2use futures::future::{ready, BoxFuture};
3use std::collections::HashMap;
4use tokio::sync::Mutex;
5
6use crate::{
7    types::{api::*, UploadClient},
8    AwsError,
9};
10
11/// For testing, a client that writes a part `n` with data `bytes` as the entry
12/// `(n, bytes)` in a hash map.
13#[derive(Debug)]
14pub struct HashMapClient {
15    store: Mutex<HashMap<i32, Vec<u8>>>,
16}
17
18impl Default for HashMapClient {
19    fn default() -> Self {
20        Self {
21            store: Mutex::new(HashMap::new()),
22        }
23    }
24}
25
26impl HashMapClient {
27    pub fn new() -> Self {
28        Self {
29            store: Mutex::new(HashMap::new()),
30        }
31    }
32
33    pub async fn clone_inner(&self) -> HashMap<i32, Vec<u8>> {
34        let map = self.store.lock().await;
35        map.clone()
36    }
37}
38
39impl UploadClient for HashMapClient {
40    fn upload_part<'a, 'c: 'a>(
41        &'c self,
42        params: &'a UploadRequestParams,
43        part_number: i32,
44        part: ByteStream,
45    ) -> BoxFuture<'a, Result<EntityTag, AwsError>> {
46        Box::pin(async move {
47            let etag = EntityTag::new(format!("{}_{}", params.key(), part_number));
48            let vec = part.collect().await.map(|data| data.to_vec())?;
49
50            let mut map = self.store.lock().await;
51            let _ = map.entry(part_number).or_insert(vec);
52
53            Ok(etag)
54        })
55    }
56
57    // This is not meaningful for this client.
58    fn new_upload<'a, 'c: 'a>(
59        &'c self,
60        addr: &'a UploadAddress,
61    ) -> BoxFuture<'a, Result<UploadRequestParams, AwsError>> {
62        let upload_id = UploadId::from(addr.key().to_string());
63        Box::pin(ready(Ok(UploadRequestParams::new(upload_id, addr.clone()))))
64    }
65
66    // This is not meaningful for this client.
67    fn complete_upload<'a, 'c: 'a>(
68        &'c self,
69        params: &'a UploadRequestParams,
70        parts: &'a UploadedParts,
71    ) -> BoxFuture<'a, Result<EntityTag, AwsError>> {
72        let etag = EntityTag::from(format!("{}_{}", params.key(), parts.last_completed()));
73        Box::pin(ready(Ok(etag)))
74    }
75}