Skip to main content

s3_wire/client/
mod.rs

1//! S3 client implementation.
2
3mod multipart;
4mod multipart_upload;
5mod object;
6mod presign;
7mod request;
8
9use std::fmt;
10use std::sync::Arc;
11
12use crate::config::S3Config;
13use crate::error::S3Error;
14use crate::transport::Transport;
15
16struct ClientInner {
17    config: S3Config,
18    transport: Transport,
19}
20
21/// An async S3-compatible client.
22#[derive(Clone)]
23pub struct S3Client {
24    inner: Arc<ClientInner>,
25}
26
27impl S3Client {
28    /// Constructs a client from validated configuration.
29    pub fn new(config: S3Config) -> Result<Self, S3Error> {
30        let transport = Transport::new(
31            config.connect_timeout(),
32            config.user_agent(),
33            !config.endpoint().is_https(),
34        )?;
35        Ok(Self {
36            inner: Arc::new(ClientInner { config, transport }),
37        })
38    }
39
40    /// Returns this client's validated configuration.
41    pub fn config(&self) -> &S3Config {
42        &self.inner.config
43    }
44
45    fn operation_target(&self, key: Option<&str>) -> Result<crate::endpoint::EndpointUrl, S3Error> {
46        self.inner.config.endpoint().object_url(
47            self.inner.config.bucket(),
48            key,
49            self.inner.config.addressing_style(),
50        )
51    }
52}
53
54impl fmt::Debug for S3Client {
55    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
56        formatter
57            .debug_struct("S3Client")
58            .field("config", &self.inner.config)
59            .finish_non_exhaustive()
60    }
61}