Skip to main content

ruma_common/api/
body.rs

1use std::convert::Infallible;
2
3use bytes::BufMut;
4
5use crate::{api::error::IntoHttpError, serde::slice_to_buf};
6
7/// HTTP message body pre-serialization.
8pub trait OutgoingBody {
9    /// The type of error that can happen in `try_info_buf`.
10    type Error: Into<IntoHttpError>;
11
12    /// Turn `self` into a byte buffer (copying a raw body or serializing a JSON one).
13    fn try_into_buf<T: Default + BufMut + AsRef<[u8]>>(self) -> Result<T, Self::Error>;
14}
15
16/// "Empty" body type, used mostly for GET requests.
17///
18/// If `TRULY_EMPTY` is `true`, serializes to an empty buffer.
19/// If `TRULY_EMPTY` is `false`, serializes to an empty JSON object.
20/// (that case is not encoded as a separate type due to macro requirements)
21#[expect(clippy::exhaustive_structs)]
22pub struct EmptyBody<const TRULY_EMPTY: bool = true>;
23
24impl<const TRULY_EMPTY: bool> OutgoingBody for EmptyBody<TRULY_EMPTY> {
25    type Error = Infallible;
26
27    fn try_into_buf<T: Default + BufMut + AsRef<[u8]>>(self) -> Result<T, Infallible> {
28        if TRULY_EMPTY { Ok(Default::default()) } else { Ok(slice_to_buf(b"{}")) }
29    }
30}
31
32/// Raw-bytes body type, used for some media endpoints.
33#[expect(clippy::exhaustive_structs)]
34pub struct BytesBody(pub Vec<u8>);
35
36impl OutgoingBody for BytesBody {
37    type Error = Infallible;
38
39    fn try_into_buf<T: Default + BufMut + AsRef<[u8]>>(self) -> Result<T, Infallible> {
40        Ok(slice_to_buf(&self.0))
41    }
42}