/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tonic-0.14.5/src/body.rs
Line | Count | Source |
1 | | //! HTTP specific body utilities. |
2 | | |
3 | | use std::{pin::Pin, task::Poll}; |
4 | | |
5 | | use http_body_util::BodyExt as _; |
6 | | |
7 | | // A type erased HTTP body. |
8 | | type BoxBody = http_body_util::combinators::UnsyncBoxBody<bytes::Bytes, crate::Status>; |
9 | | |
10 | | /// A body type used in `tonic`. |
11 | | #[derive(Debug)] |
12 | | pub struct Body { |
13 | | kind: Kind, |
14 | | } |
15 | | |
16 | | #[derive(Debug)] |
17 | | enum Kind { |
18 | | Empty, |
19 | | Wrap(BoxBody), |
20 | | } |
21 | | |
22 | | impl Body { |
23 | 0 | fn from_kind(kind: Kind) -> Self { |
24 | 0 | Self { kind } |
25 | 0 | } |
26 | | |
27 | | /// Create a new empty `Body`. |
28 | 0 | pub const fn empty() -> Self { |
29 | 0 | Self { kind: Kind::Empty } |
30 | 0 | } |
31 | | |
32 | | /// Create a new `Body` from an existing `Body`. |
33 | 0 | pub fn new<B>(body: B) -> Self |
34 | 0 | where |
35 | 0 | B: http_body::Body<Data = bytes::Bytes> + Send + 'static, |
36 | 0 | B::Error: Into<crate::BoxError>, |
37 | | { |
38 | 0 | if body.is_end_stream() { |
39 | 0 | return Self::empty(); |
40 | 0 | } |
41 | | |
42 | 0 | let mut body = Some(body); |
43 | | |
44 | 0 | if let Some(body) = <dyn std::any::Any>::downcast_mut::<Option<Body>>(&mut body) { |
45 | 0 | return body.take().unwrap(); |
46 | 0 | } |
47 | | |
48 | 0 | if let Some(body) = <dyn std::any::Any>::downcast_mut::<Option<BoxBody>>(&mut body) { |
49 | 0 | return Self::from_kind(Kind::Wrap(body.take().unwrap())); |
50 | 0 | } |
51 | | |
52 | 0 | let body = body |
53 | 0 | .unwrap() |
54 | 0 | .map_err(crate::Status::map_error) |
55 | 0 | .boxed_unsync(); |
56 | | |
57 | 0 | Self::from_kind(Kind::Wrap(body)) |
58 | 0 | } Unexecuted instantiation: <tonic::body::Body>::new::<axum_core::body::Body> Unexecuted instantiation: <tonic::body::Body>::new::<hyper::body::incoming::Incoming> |
59 | | } |
60 | | |
61 | | impl Default for Body { |
62 | 0 | fn default() -> Self { |
63 | 0 | Self::empty() |
64 | 0 | } |
65 | | } |
66 | | |
67 | | impl http_body::Body for Body { |
68 | | type Data = bytes::Bytes; |
69 | | type Error = crate::Status; |
70 | | |
71 | 0 | fn poll_frame( |
72 | 0 | mut self: std::pin::Pin<&mut Self>, |
73 | 0 | cx: &mut std::task::Context<'_>, |
74 | 0 | ) -> Poll<Option<Result<http_body::Frame<Self::Data>, Self::Error>>> { |
75 | 0 | match &mut self.kind { |
76 | 0 | Kind::Empty => Poll::Ready(None), |
77 | 0 | Kind::Wrap(body) => Pin::new(body).poll_frame(cx), |
78 | | } |
79 | 0 | } |
80 | | |
81 | 0 | fn size_hint(&self) -> http_body::SizeHint { |
82 | 0 | match &self.kind { |
83 | 0 | Kind::Empty => http_body::SizeHint::with_exact(0), |
84 | 0 | Kind::Wrap(body) => body.size_hint(), |
85 | | } |
86 | 0 | } |
87 | | |
88 | 0 | fn is_end_stream(&self) -> bool { |
89 | 0 | match &self.kind { |
90 | 0 | Kind::Empty => true, |
91 | 0 | Kind::Wrap(body) => body.is_end_stream(), |
92 | | } |
93 | 0 | } |
94 | | } |