Skip to main content

arminius_lib_roomservice_client/
ruma_response_wrapper.rs

1// SPDX-FileCopyrightText: 2025 BWI GmbH
2//
3// SPDX-License-Identifier: Apache-2.0
4
5//! Implements a wrapper for ruma responses, that can be serialized. See also
6//! [ruma_request_wrapper](crate::ruma_request_wrapper)
7
8mod tests;
9
10use axum::http::Response;
11use ruma::api::{IncomingResponse, IncomingResponseExt, OutgoingResponse, OutgoingResponseExt};
12use serde::{Deserialize, Serialize, de::Error as _, ser::Error as _};
13
14/// A wrapper around ruma Response types, that serializes them by turning them
15/// into bytes
16#[derive(Debug)]
17pub struct SerializingRumaResponseWrapper<T: IncomingResponse + OutgoingResponse + Clone>(pub T);
18
19impl<T: Clone + IncomingResponse + OutgoingResponse> Serialize
20	for SerializingRumaResponseWrapper<T>
21{
22	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
23	where
24		S: serde::Serializer,
25	{
26		let body: Vec<u8> = self
27			.0
28			.clone()
29			.try_into_http_response()
30			.map_err(|err| {
31				S::Error::custom(format!("Failed serializing into HTTP request: {err}"))
32			})?
33			.into_body();
34		serializer.serialize_bytes(&body)
35	}
36}
37
38impl<'de, T: IncomingResponseExt + OutgoingResponseExt + Clone> Deserialize<'de>
39	for SerializingRumaResponseWrapper<T>
40{
41	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
42	where
43		D: serde::Deserializer<'de>,
44	{
45		let response: Response<Vec<u8>> = Response::new(Vec::<u8>::deserialize(deserializer)?);
46		let (parts, body) = response.into_parts();
47		let response: Response<&[u8]> = Response::from_parts(parts, &body[..]);
48
49		Ok(SerializingRumaResponseWrapper(T::try_from_http_response(response).map_err(|err| {
50			D::Error::custom(format!("Failed deserializing HTTP request: {err}"))
51		})?))
52	}
53}