rama_http_hyperium/into_rama/
body.rs1use std::fmt;
5use std::pin::Pin;
6use std::task::{Context, Poll};
7
8use pin_project_lite::pin_project;
9use rama_http_types::body::http_body as rama_body;
10
11use super::TryIntoRamaHttp as _;
12
13fn size_hint_to_rama(hint: &http_body::SizeHint) -> rama_body::SizeHint {
14 let mut out = rama_body::SizeHint::new();
15 out.set_lower(hint.lower());
16 if let Some(upper) = hint.upper() {
17 out.set_upper(upper);
18 }
19 out
20}
21
22pin_project! {
23 pub struct RamaBody<B> {
26 #[pin]
27 inner: B,
28 }
29}
30
31impl<B> RamaBody<B> {
32 pub const fn new(inner: B) -> Self {
34 Self { inner }
35 }
36
37 pub fn into_inner(self) -> B {
39 self.inner
40 }
41}
42
43impl<B: http_body::Body> rama_body::Body for RamaBody<B> {
44 type Data = B::Data;
45 type Error = RamaBodyError<B::Error>;
46
47 fn poll_frame(
48 self: Pin<&mut Self>,
49 cx: &mut Context<'_>,
50 ) -> Poll<Option<Result<rama_body::Frame<Self::Data>, Self::Error>>> {
51 match self.project().inner.poll_frame(cx) {
52 Poll::Ready(Some(Ok(frame))) => match frame.into_data() {
53 Ok(data) => Poll::Ready(Some(Ok(rama_body::Frame::data(data)))),
54 Err(frame) => match frame.into_trailers() {
55 Ok(trailers) => Poll::Ready(Some(
56 trailers
57 .try_into_rama_http()
58 .map(rama_body::Frame::trailers)
59 .map_err(RamaBodyError::Trailers),
60 )),
61 Err(_) => Poll::Ready(None),
63 },
64 },
65 Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(RamaBodyError::Body(err)))),
66 Poll::Ready(None) => Poll::Ready(None),
67 Poll::Pending => Poll::Pending,
68 }
69 }
70
71 fn is_end_stream(&self) -> bool {
72 self.inner.is_end_stream()
73 }
74
75 fn size_hint(&self) -> rama_body::SizeHint {
76 size_hint_to_rama(&self.inner.size_hint())
77 }
78}
79
80#[derive(Debug)]
83pub enum RamaBodyError<E> {
84 Body(E),
86 Trailers(rama_http_types::Error),
88}
89
90impl<E: fmt::Display> fmt::Display for RamaBodyError<E> {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 match self {
93 Self::Body(err) => write!(f, "http body error: {err}"),
94 Self::Trailers(err) => write!(f, "trailer conversion to rama failed: {err}"),
95 }
96 }
97}
98
99impl<E: std::error::Error + 'static> std::error::Error for RamaBodyError<E> {
100 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
101 match self {
102 Self::Body(err) => Some(err),
103 Self::Trailers(err) => Some(err),
104 }
105 }
106}