Skip to main content

rustack_ses_http/
dispatch.rs

1//! SES handler trait and operation dispatch.
2
3use std::{future::Future, pin::Pin, sync::Arc};
4
5use bytes::Bytes;
6use rustack_ses_model::{error::SesError, operations::SesOperation};
7
8use crate::body::SesResponseBody;
9
10/// Trait that the SES business logic provider must implement.
11///
12/// The handler receives a parsed operation enum and the raw form body bytes.
13/// SES v1 receives form-urlencoded params (awsQuery protocol).
14pub trait SesHandler: Send + Sync + 'static {
15    /// Handle an SES v1 operation and produce an HTTP response.
16    fn handle_operation(
17        &self,
18        op: SesOperation,
19        body: Bytes,
20    ) -> Pin<Box<dyn Future<Output = Result<http::Response<SesResponseBody>, SesError>> + Send>>;
21
22    /// Handle an SES v2 operation and produce an HTTP response.
23    fn handle_v2_operation(
24        &self,
25        method: http::Method,
26        path: String,
27        body: Bytes,
28    ) -> Pin<Box<dyn Future<Output = Result<http::Response<SesResponseBody>, SesError>> + Send>>;
29
30    /// Query sent emails for the retrospection endpoint.
31    ///
32    /// Returns a JSON string of `{ "messages": [...] }`.
33    fn query_emails(&self, filter_id: Option<&str>, filter_source: Option<&str>) -> String;
34
35    /// Clear sent emails for the retrospection endpoint.
36    fn clear_emails(&self, filter_id: Option<&str>);
37}
38
39/// Dispatch an SES operation to the handler.
40pub async fn dispatch_operation<H: SesHandler>(
41    handler: &H,
42    op: SesOperation,
43    body: Bytes,
44) -> Result<http::Response<SesResponseBody>, SesError> {
45    tracing::debug!(operation = %op, "dispatching SES operation");
46    handler.handle_operation(op, body).await
47}
48
49/// Wrapper to hold handler behind Arc for cloning in service layer.
50#[derive(Debug, Clone)]
51pub struct SesHandlerRef<H: SesHandler> {
52    inner: Arc<H>,
53}
54
55impl<H: SesHandler> SesHandlerRef<H> {
56    /// Create a new handler reference.
57    pub fn new(handler: Arc<H>) -> Self {
58        Self { inner: handler }
59    }
60
61    /// Get the inner handler.
62    #[must_use]
63    pub fn handler(&self) -> &H {
64        &self.inner
65    }
66}