/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tonic-0.12.3/src/response.rs
Line | Count | Source |
1 | | use http::Extensions; |
2 | | |
3 | | use crate::metadata::MetadataMap; |
4 | | |
5 | | /// A gRPC response and metadata from an RPC call. |
6 | | #[derive(Debug)] |
7 | | pub struct Response<T> { |
8 | | metadata: MetadataMap, |
9 | | message: T, |
10 | | extensions: Extensions, |
11 | | } |
12 | | |
13 | | impl<T> Response<T> { |
14 | | /// Create a new gRPC response. |
15 | | /// |
16 | | /// ```rust |
17 | | /// # use tonic::Response; |
18 | | /// # pub struct HelloReply { |
19 | | /// # pub message: String, |
20 | | /// # } |
21 | | /// # let name = ""; |
22 | | /// Response::new(HelloReply { |
23 | | /// message: format!("Hello, {}!", name).into(), |
24 | | /// }); |
25 | | /// ``` |
26 | 0 | pub fn new(message: T) -> Self { |
27 | 0 | Response { |
28 | 0 | metadata: MetadataMap::new(), |
29 | 0 | message, |
30 | 0 | extensions: Extensions::new(), |
31 | 0 | } |
32 | 0 | } |
33 | | |
34 | | /// Get a immutable reference to `T`. |
35 | 0 | pub fn get_ref(&self) -> &T { |
36 | 0 | &self.message |
37 | 0 | } |
38 | | |
39 | | /// Get a mutable reference to the message |
40 | 0 | pub fn get_mut(&mut self) -> &mut T { |
41 | 0 | &mut self.message |
42 | 0 | } |
43 | | |
44 | | /// Get a reference to the custom response metadata. |
45 | 0 | pub fn metadata(&self) -> &MetadataMap { |
46 | 0 | &self.metadata |
47 | 0 | } |
48 | | |
49 | | /// Get a mutable reference to the response metadata. |
50 | 0 | pub fn metadata_mut(&mut self) -> &mut MetadataMap { |
51 | 0 | &mut self.metadata |
52 | 0 | } |
53 | | |
54 | | /// Consumes `self`, returning the message |
55 | 0 | pub fn into_inner(self) -> T { |
56 | 0 | self.message |
57 | 0 | } |
58 | | |
59 | | /// Consumes `self` returning the parts of the response. |
60 | 0 | pub fn into_parts(self) -> (MetadataMap, T, Extensions) { |
61 | 0 | (self.metadata, self.message, self.extensions) |
62 | 0 | } |
63 | | |
64 | | /// Create a new gRPC response from metadata, message and extensions. |
65 | 0 | pub fn from_parts(metadata: MetadataMap, message: T, extensions: Extensions) -> Self { |
66 | 0 | Self { |
67 | 0 | metadata, |
68 | 0 | message, |
69 | 0 | extensions, |
70 | 0 | } |
71 | 0 | } |
72 | | |
73 | 0 | pub(crate) fn from_http(res: http::Response<T>) -> Self { |
74 | 0 | let (head, message) = res.into_parts(); |
75 | 0 | Response { |
76 | 0 | metadata: MetadataMap::from_headers(head.headers), |
77 | 0 | message, |
78 | 0 | extensions: head.extensions, |
79 | 0 | } |
80 | 0 | } |
81 | | |
82 | 0 | pub(crate) fn into_http(self) -> http::Response<T> { |
83 | 0 | let mut res = http::Response::new(self.message); |
84 | | |
85 | 0 | *res.version_mut() = http::Version::HTTP_2; |
86 | 0 | *res.headers_mut() = self.metadata.into_sanitized_headers(); |
87 | 0 | *res.extensions_mut() = self.extensions; |
88 | | |
89 | 0 | res |
90 | 0 | } |
91 | | |
92 | | #[doc(hidden)] |
93 | 0 | pub fn map<F, U>(self, f: F) -> Response<U> |
94 | 0 | where |
95 | 0 | F: FnOnce(T) -> U, |
96 | | { |
97 | 0 | let message = f(self.message); |
98 | 0 | Response { |
99 | 0 | metadata: self.metadata, |
100 | 0 | message, |
101 | 0 | extensions: self.extensions, |
102 | 0 | } |
103 | 0 | } |
104 | | |
105 | | /// Returns a reference to the associated extensions. |
106 | 0 | pub fn extensions(&self) -> &Extensions { |
107 | 0 | &self.extensions |
108 | 0 | } |
109 | | |
110 | | /// Returns a mutable reference to the associated extensions. |
111 | 0 | pub fn extensions_mut(&mut self) -> &mut Extensions { |
112 | 0 | &mut self.extensions |
113 | 0 | } |
114 | | |
115 | | /// Disable compression of the response body. |
116 | | /// |
117 | | /// This disables compression of the body of this response, even if compression is enabled on |
118 | | /// the server. |
119 | | /// |
120 | | /// **Note**: This only has effect on responses to unary requests and responses to client to |
121 | | /// server streams. Response streams (server to client stream and bidirectional streams) will |
122 | | /// still be compressed according to the configuration of the server. |
123 | | #[cfg(feature = "gzip")] |
124 | | pub fn disable_compression(&mut self) { |
125 | | self.extensions_mut() |
126 | | .insert(crate::codec::compression::SingleMessageCompressionOverride::Disable); |
127 | | } |
128 | | } |
129 | | |
130 | | #[cfg(test)] |
131 | | mod tests { |
132 | | use super::*; |
133 | | use crate::metadata::{MetadataKey, MetadataValue}; |
134 | | |
135 | | #[test] |
136 | | fn reserved_headers_are_excluded() { |
137 | | let mut r = Response::new(1); |
138 | | |
139 | | for header in &MetadataMap::GRPC_RESERVED_HEADERS { |
140 | | r.metadata_mut().insert( |
141 | | MetadataKey::unchecked_from_header_name(header.clone()), |
142 | | MetadataValue::from_static("invalid"), |
143 | | ); |
144 | | } |
145 | | |
146 | | let http_response = r.into_http(); |
147 | | assert!(http_response.headers().is_empty()); |
148 | | } |
149 | | } |