cloudevents/binding/poem/
response.rs

1use crate::{AttributesReader, Data, Event};
2
3use bytes::Bytes;
4use poem_lib::http::StatusCode;
5use poem_lib::{IntoResponse, Response};
6
7impl IntoResponse for Event {
8    fn into_response(self) -> Response {
9        let mut builder = Response::builder().status(StatusCode::OK);
10
11        if let Some(dct) = self.datacontenttype() {
12            builder = builder.content_type(dct);
13        }
14
15        for (key, value) in self.iter() {
16            builder = builder.header(format!("ce-{key}").as_str(), value.to_string());
17        }
18
19        match self.data {
20            Some(data) => match data {
21                Data::Binary(v) => builder.body(Bytes::copy_from_slice(v.as_slice())),
22                Data::String(s) => builder.body(s.clone()),
23                Data::Json(j) => match serde_json::to_string(&j) {
24                    Ok(s) => builder.body(s),
25                    Err(e) => Response::builder()
26                        .status(StatusCode::INTERNAL_SERVER_ERROR)
27                        .body(e.to_string()),
28                },
29            },
30            None => builder.finish(),
31        }
32    }
33}
34
35#[cfg(test)]
36mod tests {
37    use crate::test::fixtures;
38    use poem_lib::IntoResponse;
39
40    #[test]
41    fn test_response() {
42        let input = fixtures::v10::minimal_string_extension();
43
44        let resp = input.into_response();
45
46        assert_eq!(
47            resp.headers()
48                .get("ce-specversion")
49                .unwrap()
50                .to_str()
51                .unwrap(),
52            "1.0"
53        );
54        assert_eq!(
55            resp.headers().get("ce-id").unwrap().to_str().unwrap(),
56            "0001"
57        );
58        assert_eq!(
59            resp.headers().get("ce-type").unwrap().to_str().unwrap(),
60            "test_event.test_application"
61        );
62        assert_eq!(
63            resp.headers().get("ce-source").unwrap().to_str().unwrap(),
64            "http://localhost/"
65        );
66        assert_eq!(
67            resp.headers().get("ce-someint").unwrap().to_str().unwrap(),
68            "10"
69        );
70    }
71
72    #[tokio::test]
73    async fn test_response_with_full_data() {
74        let input = fixtures::v10::full_binary_json_data_string_extension();
75
76        let resp = input.into_response();
77
78        assert_eq!(
79            resp.headers()
80                .get("ce-specversion")
81                .unwrap()
82                .to_str()
83                .unwrap(),
84            "1.0"
85        );
86        assert_eq!(
87            resp.headers().get("ce-id").unwrap().to_str().unwrap(),
88            "0001"
89        );
90        assert_eq!(
91            resp.headers().get("ce-type").unwrap().to_str().unwrap(),
92            "test_event.test_application"
93        );
94        assert_eq!(
95            resp.headers().get("ce-source").unwrap().to_str().unwrap(),
96            "http://localhost/"
97        );
98        assert_eq!(
99            resp.headers()
100                .get("content-type")
101                .unwrap()
102                .to_str()
103                .unwrap(),
104            "application/json"
105        );
106        assert_eq!(
107            resp.headers().get("ce-int_ex").unwrap().to_str().unwrap(),
108            "10"
109        );
110
111        let body = resp.into_body().into_vec().await.unwrap();
112        assert_eq!(fixtures::json_data_binary(), body);
113    }
114}