Skip to main content

s4_server/
service_arc.rs

1//! Arc-shareable wrapper around `S4Service<B>` (v0.7 #45).
2//!
3//! Background: the v0.7 #45 lifecycle scanner needs an `Arc<S4Service<B>>`
4//! handle so a long-running tokio task can call `list_objects_v2` /
5//! `head_object` / `delete_object` against the same service the hyper
6//! listener is serving. The s3s framework's
7//! [`s3s::service::S3ServiceBuilder::new`] takes `s3: impl S3` by value
8//! (and internally wraps in `Arc::new`), so a plain `Arc<S4Service<B>>`
9//! cannot be passed directly — the trait bound `Arc<S4Service<B>>: S3`
10//! is not satisfied automatically.
11//!
12//! This module provides [`SharedService`], a thin newtype around
13//! `Arc<S4Service<B>>` with a delegating `impl S3` that forwards every
14//! call to the inner service. Cloning a `SharedService` is one
15//! `Arc::clone` — the scanner keeps one clone, the s3s service builder
16//! consumes another.
17//!
18//! ## why a newtype with a single-shot impl macro
19//!
20//! `#[async_trait::async_trait]` is a proc-macro that rewrites every
21//! `async fn` it can directly see into a desugared `Pin<Box<dyn Future
22//! ...>>` return. Proc macros run **before** `macro_rules!` expand, so a
23//! per-method `delegate!` macro inside the impl body would be invisible
24//! to `async_trait` (the result is `E0195` lifetime mismatches on every
25//! method). To work around that ordering, the entire `impl S3 for
26//! SharedService<B>` block is generated by the [`s3_delegate_impl!`]
27//! `macro_rules!` below, so `#[async_trait::async_trait]` sees the
28//! `async fn`s after the macro has expanded.
29
30use std::sync::Arc;
31
32use s3s::dto::*;
33use s3s::{S3, S3Request, S3Response, S3Result};
34
35use crate::service::S4Service;
36
37/// Cheap-clone shared handle to an `S4Service<B>`. Implements `S3` by
38/// delegating every call through the inner Arc. Construct via
39/// [`SharedService::new`]; `Clone` bumps the refcount only.
40pub struct SharedService<B: S3 + Send + Sync + 'static> {
41    inner: Arc<S4Service<B>>,
42}
43
44impl<B: S3 + Send + Sync + 'static> SharedService<B> {
45    /// Wrap an existing `Arc<S4Service<B>>`. Useful when the caller
46    /// already holds the `Arc` (e.g. the lifecycle scheduler in
47    /// `main.rs` clones it for the background task before handing the
48    /// service to the s3s builder).
49    #[must_use]
50    pub fn new(inner: Arc<S4Service<B>>) -> Self {
51        Self { inner }
52    }
53
54    /// Borrow the underlying `Arc` so the lifecycle scanner /
55    /// background scheduler can issue `S3` calls without re-cloning.
56    #[must_use]
57    pub fn arc(&self) -> &Arc<S4Service<B>> {
58        &self.inner
59    }
60}
61
62impl<B: S3 + Send + Sync + 'static> Clone for SharedService<B> {
63    fn clone(&self) -> Self {
64        Self {
65            inner: Arc::clone(&self.inner),
66        }
67    }
68}
69
70impl<B: S3 + Send + Sync + 'static> std::fmt::Debug for SharedService<B> {
71    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72        f.debug_struct("SharedService")
73            .field("inner", &"<Arc<S4Service<...>>>")
74            .finish()
75    }
76}
77
78/// Generate the full delegating `impl S3 for SharedService<B>` block.
79/// Macro-emitted so `#[async_trait::async_trait]` can rewrite each
80/// `async fn` (proc macros run before `macro_rules!` expand, so a
81/// per-method macro inside the impl body would be invisible to
82/// `async_trait`).
83macro_rules! s3_delegate_impl {
84    ( $( ($name:ident, $input:ident, $output:ident) ),* $(,)? ) => {
85        #[async_trait::async_trait]
86        impl<B: S3 + Send + Sync + 'static> S3 for SharedService<B> {
87            $(
88                async fn $name(
89                    &self,
90                    req: S3Request<$input>,
91                ) -> S3Result<S3Response<$output>> {
92                    (*self.inner).$name(req).await
93                }
94            )*
95        }
96    };
97}
98
99s3_delegate_impl! {
100    (abort_multipart_upload, AbortMultipartUploadInput, AbortMultipartUploadOutput),
101    (complete_multipart_upload, CompleteMultipartUploadInput, CompleteMultipartUploadOutput),
102    (copy_object, CopyObjectInput, CopyObjectOutput),
103    (create_bucket, CreateBucketInput, CreateBucketOutput),
104    (create_bucket_metadata_table_configuration, CreateBucketMetadataTableConfigurationInput, CreateBucketMetadataTableConfigurationOutput),
105    (create_multipart_upload, CreateMultipartUploadInput, CreateMultipartUploadOutput),
106    (create_session, CreateSessionInput, CreateSessionOutput),
107    (delete_bucket, DeleteBucketInput, DeleteBucketOutput),
108    (delete_bucket_analytics_configuration, DeleteBucketAnalyticsConfigurationInput, DeleteBucketAnalyticsConfigurationOutput),
109    (delete_bucket_cors, DeleteBucketCorsInput, DeleteBucketCorsOutput),
110    (delete_bucket_encryption, DeleteBucketEncryptionInput, DeleteBucketEncryptionOutput),
111    (delete_bucket_intelligent_tiering_configuration, DeleteBucketIntelligentTieringConfigurationInput, DeleteBucketIntelligentTieringConfigurationOutput),
112    (delete_bucket_inventory_configuration, DeleteBucketInventoryConfigurationInput, DeleteBucketInventoryConfigurationOutput),
113    (delete_bucket_lifecycle, DeleteBucketLifecycleInput, DeleteBucketLifecycleOutput),
114    (delete_bucket_metadata_table_configuration, DeleteBucketMetadataTableConfigurationInput, DeleteBucketMetadataTableConfigurationOutput),
115    (delete_bucket_metrics_configuration, DeleteBucketMetricsConfigurationInput, DeleteBucketMetricsConfigurationOutput),
116    (delete_bucket_ownership_controls, DeleteBucketOwnershipControlsInput, DeleteBucketOwnershipControlsOutput),
117    (delete_bucket_policy, DeleteBucketPolicyInput, DeleteBucketPolicyOutput),
118    (delete_bucket_replication, DeleteBucketReplicationInput, DeleteBucketReplicationOutput),
119    (delete_bucket_tagging, DeleteBucketTaggingInput, DeleteBucketTaggingOutput),
120    (delete_bucket_website, DeleteBucketWebsiteInput, DeleteBucketWebsiteOutput),
121    (delete_object, DeleteObjectInput, DeleteObjectOutput),
122    (delete_object_tagging, DeleteObjectTaggingInput, DeleteObjectTaggingOutput),
123    (delete_objects, DeleteObjectsInput, DeleteObjectsOutput),
124    (delete_public_access_block, DeletePublicAccessBlockInput, DeletePublicAccessBlockOutput),
125    (get_bucket_accelerate_configuration, GetBucketAccelerateConfigurationInput, GetBucketAccelerateConfigurationOutput),
126    (get_bucket_acl, GetBucketAclInput, GetBucketAclOutput),
127    (get_bucket_analytics_configuration, GetBucketAnalyticsConfigurationInput, GetBucketAnalyticsConfigurationOutput),
128    (get_bucket_cors, GetBucketCorsInput, GetBucketCorsOutput),
129    (get_bucket_encryption, GetBucketEncryptionInput, GetBucketEncryptionOutput),
130    (get_bucket_intelligent_tiering_configuration, GetBucketIntelligentTieringConfigurationInput, GetBucketIntelligentTieringConfigurationOutput),
131    (get_bucket_inventory_configuration, GetBucketInventoryConfigurationInput, GetBucketInventoryConfigurationOutput),
132    (get_bucket_lifecycle_configuration, GetBucketLifecycleConfigurationInput, GetBucketLifecycleConfigurationOutput),
133    (get_bucket_location, GetBucketLocationInput, GetBucketLocationOutput),
134    (get_bucket_logging, GetBucketLoggingInput, GetBucketLoggingOutput),
135    (get_bucket_metadata_table_configuration, GetBucketMetadataTableConfigurationInput, GetBucketMetadataTableConfigurationOutput),
136    (get_bucket_metrics_configuration, GetBucketMetricsConfigurationInput, GetBucketMetricsConfigurationOutput),
137    (get_bucket_notification_configuration, GetBucketNotificationConfigurationInput, GetBucketNotificationConfigurationOutput),
138    (get_bucket_ownership_controls, GetBucketOwnershipControlsInput, GetBucketOwnershipControlsOutput),
139    (get_bucket_policy, GetBucketPolicyInput, GetBucketPolicyOutput),
140    (get_bucket_policy_status, GetBucketPolicyStatusInput, GetBucketPolicyStatusOutput),
141    (get_bucket_replication, GetBucketReplicationInput, GetBucketReplicationOutput),
142    (get_bucket_request_payment, GetBucketRequestPaymentInput, GetBucketRequestPaymentOutput),
143    (get_bucket_tagging, GetBucketTaggingInput, GetBucketTaggingOutput),
144    (get_bucket_versioning, GetBucketVersioningInput, GetBucketVersioningOutput),
145    (get_bucket_website, GetBucketWebsiteInput, GetBucketWebsiteOutput),
146    (get_object, GetObjectInput, GetObjectOutput),
147    (get_object_acl, GetObjectAclInput, GetObjectAclOutput),
148    (get_object_attributes, GetObjectAttributesInput, GetObjectAttributesOutput),
149    (get_object_legal_hold, GetObjectLegalHoldInput, GetObjectLegalHoldOutput),
150    (get_object_lock_configuration, GetObjectLockConfigurationInput, GetObjectLockConfigurationOutput),
151    (get_object_retention, GetObjectRetentionInput, GetObjectRetentionOutput),
152    (get_object_tagging, GetObjectTaggingInput, GetObjectTaggingOutput),
153    (get_object_torrent, GetObjectTorrentInput, GetObjectTorrentOutput),
154    (get_public_access_block, GetPublicAccessBlockInput, GetPublicAccessBlockOutput),
155    (head_bucket, HeadBucketInput, HeadBucketOutput),
156    (head_object, HeadObjectInput, HeadObjectOutput),
157    (list_bucket_analytics_configurations, ListBucketAnalyticsConfigurationsInput, ListBucketAnalyticsConfigurationsOutput),
158    (list_bucket_intelligent_tiering_configurations, ListBucketIntelligentTieringConfigurationsInput, ListBucketIntelligentTieringConfigurationsOutput),
159    (list_bucket_inventory_configurations, ListBucketInventoryConfigurationsInput, ListBucketInventoryConfigurationsOutput),
160    (list_bucket_metrics_configurations, ListBucketMetricsConfigurationsInput, ListBucketMetricsConfigurationsOutput),
161    (list_buckets, ListBucketsInput, ListBucketsOutput),
162    (list_directory_buckets, ListDirectoryBucketsInput, ListDirectoryBucketsOutput),
163    (list_multipart_uploads, ListMultipartUploadsInput, ListMultipartUploadsOutput),
164    (list_object_versions, ListObjectVersionsInput, ListObjectVersionsOutput),
165    (list_objects, ListObjectsInput, ListObjectsOutput),
166    (list_objects_v2, ListObjectsV2Input, ListObjectsV2Output),
167    (list_parts, ListPartsInput, ListPartsOutput),
168    (post_object, PostObjectInput, PostObjectOutput),
169    (put_bucket_accelerate_configuration, PutBucketAccelerateConfigurationInput, PutBucketAccelerateConfigurationOutput),
170    (put_bucket_acl, PutBucketAclInput, PutBucketAclOutput),
171    (put_bucket_analytics_configuration, PutBucketAnalyticsConfigurationInput, PutBucketAnalyticsConfigurationOutput),
172    (put_bucket_cors, PutBucketCorsInput, PutBucketCorsOutput),
173    (put_bucket_encryption, PutBucketEncryptionInput, PutBucketEncryptionOutput),
174    (put_bucket_intelligent_tiering_configuration, PutBucketIntelligentTieringConfigurationInput, PutBucketIntelligentTieringConfigurationOutput),
175    (put_bucket_inventory_configuration, PutBucketInventoryConfigurationInput, PutBucketInventoryConfigurationOutput),
176    (put_bucket_lifecycle_configuration, PutBucketLifecycleConfigurationInput, PutBucketLifecycleConfigurationOutput),
177    (put_bucket_logging, PutBucketLoggingInput, PutBucketLoggingOutput),
178    (put_bucket_metrics_configuration, PutBucketMetricsConfigurationInput, PutBucketMetricsConfigurationOutput),
179    (put_bucket_notification_configuration, PutBucketNotificationConfigurationInput, PutBucketNotificationConfigurationOutput),
180    (put_bucket_ownership_controls, PutBucketOwnershipControlsInput, PutBucketOwnershipControlsOutput),
181    (put_bucket_policy, PutBucketPolicyInput, PutBucketPolicyOutput),
182    (put_bucket_replication, PutBucketReplicationInput, PutBucketReplicationOutput),
183    (put_bucket_request_payment, PutBucketRequestPaymentInput, PutBucketRequestPaymentOutput),
184    (put_bucket_tagging, PutBucketTaggingInput, PutBucketTaggingOutput),
185    (put_bucket_versioning, PutBucketVersioningInput, PutBucketVersioningOutput),
186    (put_bucket_website, PutBucketWebsiteInput, PutBucketWebsiteOutput),
187    (put_object, PutObjectInput, PutObjectOutput),
188    (put_object_acl, PutObjectAclInput, PutObjectAclOutput),
189    (put_object_legal_hold, PutObjectLegalHoldInput, PutObjectLegalHoldOutput),
190    (put_object_lock_configuration, PutObjectLockConfigurationInput, PutObjectLockConfigurationOutput),
191    (put_object_retention, PutObjectRetentionInput, PutObjectRetentionOutput),
192    (put_object_tagging, PutObjectTaggingInput, PutObjectTaggingOutput),
193    (put_public_access_block, PutPublicAccessBlockInput, PutPublicAccessBlockOutput),
194    (restore_object, RestoreObjectInput, RestoreObjectOutput),
195    (select_object_content, SelectObjectContentInput, SelectObjectContentOutput),
196    (upload_part, UploadPartInput, UploadPartOutput),
197    (upload_part_copy, UploadPartCopyInput, UploadPartCopyOutput),
198    (write_get_object_response, WriteGetObjectResponseInput, WriteGetObjectResponseOutput),
199}