1use std::convert::Infallible;
2
3use bytes::BufMut;
4
5use crate::{api::error::IntoHttpError, serde::slice_to_buf};
6
7pub trait OutgoingBody {
9 type Error: Into<IntoHttpError>;
11
12 fn content_type(&self) -> Option<http::HeaderValue>;
19
20 fn try_into_buf<T: Default + BufMut + AsRef<[u8]>>(self) -> Result<T, Self::Error>;
22}
23
24#[expect(clippy::exhaustive_structs)]
30pub struct EmptyBody<const TRULY_EMPTY: bool = true>;
31
32impl<const TRULY_EMPTY: bool> OutgoingBody for EmptyBody<TRULY_EMPTY> {
33 type Error = Infallible;
34
35 fn content_type(&self) -> Option<http::HeaderValue> {
36 if TRULY_EMPTY { None } else { Some(crate::http_headers::APPLICATION_JSON) }
37 }
38
39 fn try_into_buf<T: Default + BufMut + AsRef<[u8]>>(self) -> Result<T, Infallible> {
40 if TRULY_EMPTY { Ok(Default::default()) } else { Ok(slice_to_buf(b"{}")) }
41 }
42}
43
44#[expect(clippy::exhaustive_structs)]
46pub struct BytesBody(pub Vec<u8>);
47
48impl OutgoingBody for BytesBody {
49 type Error = Infallible;
50
51 fn content_type(&self) -> Option<http::HeaderValue> {
52 Some(crate::http_headers::APPLICATION_OCTET_STREAM)
53 }
54
55 fn try_into_buf<T: Default + BufMut + AsRef<[u8]>>(self) -> Result<T, Infallible> {
56 Ok(slice_to_buf(&self.0))
57 }
58}