/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tonic-0.13.0/src/service/layered.rs
Line | Count | Source |
1 | | use std::{ |
2 | | marker::PhantomData, |
3 | | task::{Context, Poll}, |
4 | | }; |
5 | | |
6 | | use tower_layer::Layer; |
7 | | use tower_service::Service; |
8 | | |
9 | | use crate::server::NamedService; |
10 | | |
11 | | /// A layered service to propagate [`NamedService`] implementation. |
12 | | #[derive(Debug, Clone)] |
13 | | pub struct Layered<S, T> { |
14 | | inner: S, |
15 | | _ty: PhantomData<T>, |
16 | | } |
17 | | |
18 | | impl<S, T: NamedService> NamedService for Layered<S, T> { |
19 | | const NAME: &'static str = T::NAME; |
20 | | } |
21 | | |
22 | | impl<Req, S, T> Service<Req> for Layered<S, T> |
23 | | where |
24 | | S: Service<Req>, |
25 | | { |
26 | | type Response = S::Response; |
27 | | type Error = S::Error; |
28 | | type Future = S::Future; |
29 | | |
30 | 0 | fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { |
31 | 0 | self.inner.poll_ready(cx) |
32 | 0 | } |
33 | | |
34 | 0 | fn call(&mut self, req: Req) -> Self::Future { |
35 | 0 | self.inner.call(req) |
36 | 0 | } |
37 | | } |
38 | | |
39 | | /// Extension trait which adds utility methods to types which implement [`tower_layer::Layer`]. |
40 | | pub trait LayerExt<L>: sealed::Sealed { |
41 | | /// Applies the layer to a service and wraps it in [`Layered`]. |
42 | | fn named_layer<S>(&self, service: S) -> Layered<L::Service, S> |
43 | | where |
44 | | L: Layer<S>; |
45 | | } |
46 | | |
47 | | impl<L> LayerExt<L> for L { |
48 | 0 | fn named_layer<S>(&self, service: S) -> Layered<<L>::Service, S> |
49 | 0 | where |
50 | 0 | L: Layer<S>, |
51 | | { |
52 | 0 | Layered { |
53 | 0 | inner: self.layer(service), |
54 | 0 | _ty: PhantomData, |
55 | 0 | } |
56 | 0 | } |
57 | | } |
58 | | |
59 | | mod sealed { |
60 | | pub trait Sealed {} |
61 | | impl<T> Sealed for T {} |
62 | | } |
63 | | |
64 | | #[cfg(test)] |
65 | | mod tests { |
66 | | use super::*; |
67 | | |
68 | | #[derive(Debug, Default)] |
69 | | struct TestService {} |
70 | | |
71 | | const TEST_SERVICE_NAME: &str = "test-service-name"; |
72 | | |
73 | | impl NamedService for TestService { |
74 | | const NAME: &'static str = TEST_SERVICE_NAME; |
75 | | } |
76 | | |
77 | | // Checks if the argument implements `NamedService` and returns the implemented `NAME`. |
78 | | fn get_name_of_named_service<S: NamedService>(_s: &S) -> &'static str { |
79 | | S::NAME |
80 | | } |
81 | | |
82 | | #[test] |
83 | | fn named_service_is_propagated_to_layered() { |
84 | | use std::time::Duration; |
85 | | use tower::{limit::ConcurrencyLimitLayer, timeout::TimeoutLayer}; |
86 | | |
87 | | let layered = TimeoutLayer::new(Duration::from_secs(5)).named_layer(TestService::default()); |
88 | | assert_eq!(get_name_of_named_service(&layered), TEST_SERVICE_NAME); |
89 | | |
90 | | let layered = ConcurrencyLimitLayer::new(3).named_layer(layered); |
91 | | assert_eq!(get_name_of_named_service(&layered), TEST_SERVICE_NAME); |
92 | | } |
93 | | } |