Skip to main content

sms_web_poem/
lib.rs

1use poem::{
2    web::{Data, Path},
3    http::{HeaderMap, StatusCode},
4    Request, Response, Result,
5};
6use bytes::Bytes;
7use sms_core::{Headers, InboundRegistry};
8use sms_web_generic::{HeaderConverter, ResponseConverter, WebhookProcessor};
9
10#[derive(Clone)]
11pub struct AppState {
12    pub registry: InboundRegistry,
13}
14
15/// Poem-specific header converter
16pub struct PoemHeaderConverter;
17
18impl HeaderConverter for PoemHeaderConverter {
19    type HeaderType = HeaderMap;
20
21    fn to_generic_headers(headers: &Self::HeaderType) -> Headers {
22        headers
23            .iter()
24            .map(|(k, v)| {
25                (
26                    k.as_str().to_string(),
27                    v.to_str().unwrap_or_default().to_string(),
28                )
29            })
30            .collect()
31    }
32}
33
34/// Poem-specific response converter
35pub struct PoemResponseConverter;
36
37impl ResponseConverter for PoemResponseConverter {
38    type ResponseType = Response;
39
40    fn from_webhook_response(response: sms_core::WebhookResponse) -> Self::ResponseType {
41        let status = StatusCode::from_u16(response.status.as_u16())
42            .unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
43
44        Response::builder()
45            .status(status)
46            .header("content-type", response.content_type)
47            .body(response.body)
48    }
49}
50
51/// Unified webhook handler for Poem
52pub async fn unified_webhook(
53    req: &Request,
54    Path(provider): Path<String>,
55    body: Bytes,
56    Data(state): Data<&AppState>,
57) -> Result<Response> {
58    let processor = WebhookProcessor::new(state.registry.clone());
59    let generic_headers = PoemHeaderConverter::to_generic_headers(req.headers());
60    let response = processor.process_webhook(&provider, generic_headers, &body);
61    Ok(PoemResponseConverter::from_webhook_response(response))
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn poem_types_compile() {
70        let registry = InboundRegistry::new();
71        let _state = AppState { registry };
72    }
73}