Skip to main content

tonic/server/
service.rs

1/*
2 *
3 * Copyright 2025 gRPC authors.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25use crate::{Request, Response, Status, Streaming};
26use std::future::Future;
27use tokio_stream::Stream;
28use tower_service::Service;
29
30/// A specialization of tower_service::Service.
31///
32/// Existing tower_service::Service implementations with the correct form will
33/// automatically implement `UnaryService`.
34pub trait UnaryService<R> {
35    /// Protobuf response message type
36    type Response;
37
38    /// Response future
39    type Future: Future<Output = Result<Response<Self::Response>, Status>>;
40
41    /// Call the service
42    fn call(&mut self, request: Request<R>) -> Self::Future;
43}
44
45impl<T, M1, M2> UnaryService<M1> for T
46where
47    T: Service<Request<M1>, Response = Response<M2>, Error = crate::Status>,
48{
49    type Response = M2;
50    type Future = T::Future;
51
52    fn call(&mut self, request: Request<M1>) -> Self::Future {
53        Service::call(self, request)
54    }
55}
56
57/// A specialization of tower_service::Service.
58///
59/// Existing tower_service::Service implementations with the correct form will
60/// automatically implement `ServerStreamingService`.
61pub trait ServerStreamingService<R> {
62    /// Protobuf response message type
63    type Response;
64
65    /// Stream of outbound response messages
66    type ResponseStream: Stream<Item = Result<Self::Response, Status>>;
67
68    /// Response future
69    type Future: Future<Output = Result<Response<Self::ResponseStream>, Status>>;
70
71    /// Call the service
72    fn call(&mut self, request: Request<R>) -> Self::Future;
73}
74
75impl<T, S, M1, M2> ServerStreamingService<M1> for T
76where
77    T: Service<Request<M1>, Response = Response<S>, Error = crate::Status>,
78    S: Stream<Item = Result<M2, crate::Status>>,
79{
80    type Response = M2;
81    type ResponseStream = S;
82    type Future = T::Future;
83
84    fn call(&mut self, request: Request<M1>) -> Self::Future {
85        Service::call(self, request)
86    }
87}
88
89/// A specialization of tower_service::Service.
90///
91/// Existing tower_service::Service implementations with the correct form will
92/// automatically implement `ClientStreamingService`.
93pub trait ClientStreamingService<R> {
94    /// Protobuf response message type
95    type Response;
96
97    /// Response future
98    type Future: Future<Output = Result<Response<Self::Response>, Status>>;
99
100    /// Call the service
101    fn call(&mut self, request: Request<Streaming<R>>) -> Self::Future;
102}
103
104impl<T, M1, M2> ClientStreamingService<M1> for T
105where
106    T: Service<Request<Streaming<M1>>, Response = Response<M2>, Error = crate::Status>,
107{
108    type Response = M2;
109    type Future = T::Future;
110
111    fn call(&mut self, request: Request<Streaming<M1>>) -> Self::Future {
112        Service::call(self, request)
113    }
114}
115
116/// A specialization of tower_service::Service.
117///
118/// Existing tower_service::Service implementations with the correct form will
119/// automatically implement `StreamingService`.
120pub trait StreamingService<R> {
121    /// Protobuf response message type
122    type Response;
123
124    /// Stream of outbound response messages
125    type ResponseStream: Stream<Item = Result<Self::Response, Status>>;
126
127    /// Response future
128    type Future: Future<Output = Result<Response<Self::ResponseStream>, Status>>;
129
130    /// Call the service
131    fn call(&mut self, request: Request<Streaming<R>>) -> Self::Future;
132}
133
134impl<T, S, M1, M2> StreamingService<M1> for T
135where
136    T: Service<Request<Streaming<M1>>, Response = Response<S>, Error = crate::Status>,
137    S: Stream<Item = Result<M2, crate::Status>>,
138{
139    type Response = M2;
140    type ResponseStream = S;
141    type Future = T::Future;
142
143    fn call(&mut self, request: Request<Streaming<M1>>) -> Self::Future {
144        Service::call(self, request)
145    }
146}