1use std::ops;
2
3use ntex_bytes::{BytePages, ByteString, Bytes};
4use ntex_http::{HeaderMap, HeaderName, HeaderValue};
5
6mod error;
7mod service;
8
9pub use self::error::{MethodResult, ServerError, StreamResult};
10pub use self::service::GrpcServer;
11pub use crate::GrpcStatus;
12
13use crate::stream::CallStreams;
14use crate::{MethodDef, RecvStream, SendStream};
15
16pub trait NamedService {
23 const NAME: &'static str;
25
26 fn is_streaming(method: &str) -> bool {
34 let _ = method;
35 false
36 }
37}
38
39#[doc(hidden)]
41pub mod __private {
42 use super::{
43 CallStreams, GrpcStatus, MethodDef, RecvStream, SendStream, ServerError, ServerRequest,
44 };
45
46 pub fn streams(req: &mut ServerRequest) -> Result<CallStreams, ServerError> {
53 req.streams.take().ok_or_else(|| {
54 ServerError::new(
55 GrpcStatus::Unimplemented,
56 crate::encode_grpc_message(&format!(
57 "Streaming is not supported for method: {}",
58 req.name
59 )),
60 None,
61 )
62 })
63 }
64
65 pub fn recv<M: MethodDef>(_: &M, streams: &mut CallStreams) -> RecvStream<M::Input> {
67 streams.recv()
68 }
69
70 pub fn send<M: MethodDef>(_: &M, streams: &mut CallStreams) -> SendStream<M::Output> {
72 streams.send()
73 }
74
75 pub const fn check_kind<M: MethodDef, const CLIENT: bool, const SERVER: bool>(_: &M) {
77 const {
78 assert!(
79 M::CLIENT_STREAMING == CLIENT && M::SERVER_STREAMING == SERVER,
80 "The method signature does not match the streaming kind of the rpc"
81 );
82 }
83 }
84}
85
86#[derive(Debug)]
93pub struct ServerRequest {
94 pub service: ByteString,
96 pub name: ByteString,
98 pub payload: Bytes,
101 pub headers: HeaderMap,
104 #[doc(hidden)]
107 pub streams: Option<CallStreams>,
108}
109
110#[derive(Debug)]
112pub struct ServerResponse {
113 pub payload: BytePages,
116 pub headers: Vec<(HeaderName, HeaderValue)>,
119}
120
121impl ServerResponse {
122 #[inline]
123 pub fn new(payload: BytePages) -> ServerResponse {
125 ServerResponse::with_headers(payload, Vec::new())
126 }
127
128 #[inline]
129 pub fn with_headers(
131 payload: BytePages,
132 headers: Vec<(HeaderName, HeaderValue)>,
133 ) -> ServerResponse {
134 ServerResponse { payload, headers }
135 }
136}
137
138pub trait FromRequest<T> {
156 fn from(input: Request<T>) -> Self;
158}
159
160pub struct Request<T> {
166 pub service: ByteString,
168 pub name: ByteString,
170 pub headers: HeaderMap,
172 pub message: T,
174}
175
176impl<T> FromRequest<T> for T {
177 #[inline]
178 fn from(input: Request<T>) -> T {
179 ntex_h2::release_header_map(input.headers);
180 input.message
181 }
182}
183
184impl<T> FromRequest<T> for Request<T> {
185 #[inline]
186 fn from(input: Request<T>) -> Request<T> {
187 input
188 }
189}
190
191impl<T> Request<T> {
192 pub fn into_inner(self) -> T {
194 ntex_h2::release_header_map(self.headers);
195 self.message
196 }
197}
198
199impl<T> ops::Deref for Request<T> {
200 type Target = T;
201
202 #[inline]
203 fn deref(&self) -> &T {
204 &self.message
205 }
206}
207
208impl<T> ops::DerefMut for Request<T> {
209 #[inline]
210 fn deref_mut(&mut self) -> &mut T {
211 &mut self.message
212 }
213}
214
215pub struct Response<T> {
221 pub message: T,
223 pub headers: Vec<(HeaderName, HeaderValue)>,
226}
227
228impl<T> Response<T> {
229 pub fn new(message: T) -> Self {
231 Self {
232 message,
233 headers: Vec::new(),
234 }
235 }
236}
237
238impl<T> From<T> for Response<T> {
239 fn from(message: T) -> Self {
240 Response {
241 message,
242 headers: Vec::new(),
243 }
244 }
245}
246
247#[cfg(test)]
248mod tests {
249 use super::*;
250
251 fn pages(data: &[u8]) -> BytePages {
252 let mut buf = BytePages::default();
253 buf.extend_from_slice(data);
254 buf
255 }
256
257 #[test]
258 fn server_response() {
259 let res = ServerResponse::new(pages(b"hi"));
260 assert_eq!(res.payload.len(), 2);
261 assert!(res.headers.is_empty());
262
263 let res = ServerResponse::with_headers(
264 pages(b"hi"),
265 vec![(
266 HeaderName::from_static("x-a"),
267 HeaderValue::from_static("1"),
268 )],
269 );
270 assert_eq!(res.headers.len(), 1);
271 assert_eq!(res.headers[0].1, HeaderValue::from_static("1"));
272 assert!(format!("{res:?}").contains("ServerResponse"));
273 }
274
275 #[test]
276 fn server_request_debug() {
277 let req = ServerRequest {
278 service: ByteString::from_static("helloworld.Greeter"),
279 name: ByteString::from_static("SayHello"),
280 payload: Bytes::from_static(b"x"),
281 headers: HeaderMap::new(),
282 streams: None,
283 };
284 assert!(format!("{req:?}").contains("SayHello"));
285 }
286
287 fn request(message: u32) -> Request<u32> {
288 let mut headers = HeaderMap::new();
289 headers.insert(
290 HeaderName::from_static("x-a"),
291 HeaderValue::from_static("1"),
292 );
293 Request {
294 service: ByteString::from_static("helloworld.Greeter"),
295 name: ByteString::from_static("SayHello"),
296 headers,
297 message,
298 }
299 }
300
301 #[test]
302 fn from_request_message() {
303 assert_eq!(<u32 as FromRequest<u32>>::from(request(5)), 5);
305 }
306
307 #[test]
308 fn from_request_full() {
309 let req = <Request<u32> as FromRequest<u32>>::from(request(6));
310 assert_eq!(req.name, "SayHello");
311 assert_eq!(
312 req.headers.get("x-a").unwrap(),
313 &HeaderValue::from_static("1")
314 );
315 assert_eq!(*req, 6);
316 assert_eq!(req.into_inner(), 6);
317 }
318
319 #[test]
320 fn request_deref_mut() {
321 let mut req = request(7);
322 *req = 8;
323 assert_eq!(req.message, 8);
324 }
325
326 #[test]
327 fn response_wrapper() {
328 let res = Response::new(1_u32);
329 assert_eq!(res.message, 1);
330 assert!(res.headers.is_empty());
331
332 let res = <Response<u32> as From<u32>>::from(2_u32);
333 assert_eq!(res.message, 2);
334 assert!(res.headers.is_empty());
335 }
336}