Coverage Report

Created: 2026-11-03 08:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}