1use super::GetSpan;
3use futures::future::Future;
4use std::marker::PhantomData;
5use std::pin::Pin;
6use std::task::{Context, Poll};
7use tracing::Instrument;
8
9#[derive(Debug)]
10pub struct Service<S, R, G = fn(&R) -> tracing::Span>
11where
12 S: tower_service::Service<R>,
13 G: GetSpan<R>,
14{
15 get_span: G,
16 inner: S,
17 _p: PhantomData<fn(R)>,
18}
19
20#[cfg(feature = "tower-layer")]
21#[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
22pub use self::layer::*;
23
24#[cfg(feature = "tower-layer")]
25#[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
26mod layer {
27 use super::*;
28
29 #[derive(Debug)]
30 pub struct Layer<R, G = fn(&R) -> tracing::Span>
31 where
32 G: GetSpan<R> + Clone,
33 {
34 get_span: G,
35 _p: PhantomData<fn(R)>,
36 }
37
38 pub fn layer<R, G>(get_span: G) -> Layer<R, G>
39 where
40 G: GetSpan<R> + Clone,
41 {
42 Layer {
43 get_span,
44 _p: PhantomData,
45 }
46 }
47
48 impl<S, R, G> tower_layer::Layer<S> for Layer<R, G>
50 where
51 S: tower_service::Service<R>,
52 G: GetSpan<R> + Clone,
53 {
54 type Service = Service<S, R, G>;
55
56 fn layer(&self, service: S) -> Self::Service {
57 Service::new(service, self.get_span.clone())
58 }
59 }
60
61 impl<R, G> Clone for Layer<R, G>
62 where
63 G: GetSpan<R> + Clone,
64 {
65 fn clone(&self) -> Self {
66 Self {
67 get_span: self.get_span.clone(),
68 _p: PhantomData,
69 }
70 }
71 }
72}
73
74#[cfg(feature = "tower-make")]
75#[cfg_attr(docsrs, doc(cfg(feature = "tower-make")))]
76pub use self::make::MakeService;
77
78#[cfg(feature = "tower-make")]
79#[cfg_attr(docsrs, doc(cfg(feature = "tower-make")))]
80pub mod make {
81 use super::*;
82 use pin_project_lite::pin_project;
83
84 #[derive(Debug)]
85 pub struct MakeService<S, R, G = fn(&R) -> tracing::Span> {
86 get_span: G,
87 inner: S,
88 _p: PhantomData<fn(R)>,
89 }
90
91 #[cfg(feature = "tower-layer")]
92 #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
93 #[derive(Debug)]
94 pub struct MakeLayer<R, T, G = fn(&R) -> tracing::Span>
95 where
96 G: GetSpan<R> + Clone,
97 {
98 get_span: G,
99 _p: PhantomData<fn(T, R)>,
100 }
101
102 pin_project! {
103 #[derive(Debug)]
104 pub struct MakeFuture<F, R, G = fn(&R) -> tracing::Span> {
105 get_span: Option<G>,
106 #[pin]
107 inner: F,
108 _p: PhantomData<fn(R)>,
109 }
110 }
111
112 #[cfg(feature = "tower-layer")]
113 #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
114 pub fn layer<R, T, G>(get_span: G) -> MakeLayer<R, T, G>
115 where
116 G: GetSpan<R> + Clone,
117 {
118 MakeLayer {
119 get_span,
120 _p: PhantomData,
121 }
122 }
123
124 #[cfg(feature = "tower-layer")]
127 #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
128 impl<S, R, G, T> tower_layer::Layer<S> for MakeLayer<R, T, G>
129 where
130 S: tower_make::MakeService<T, R>,
131 G: GetSpan<R> + Clone,
132 {
133 type Service = MakeService<S, R, G>;
134
135 fn layer(&self, inner: S) -> Self::Service {
136 MakeService::new(inner, self.get_span.clone())
137 }
138 }
139
140 #[cfg(feature = "tower-layer")]
141 #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
142 impl<R, T, G> Clone for MakeLayer<R, T, G>
143 where
144 G: GetSpan<R> + Clone,
145 {
146 fn clone(&self) -> Self {
147 Self {
148 get_span: self.get_span.clone(),
149 _p: PhantomData,
150 }
151 }
152 }
153
154 impl<S, R, G, T> tower_service::Service<T> for MakeService<S, R, G>
157 where
158 S: tower_make::MakeService<T, R>,
159 G: GetSpan<R> + Clone,
160 {
161 type Response = Service<S::Service, R, G>;
162 type Error = S::MakeError;
163 type Future = MakeFuture<S::Future, R, G>;
164
165 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
166 self.inner.poll_ready(cx)
167 }
168
169 fn call(&mut self, target: T) -> Self::Future {
170 let inner = self.inner.make_service(target);
171 let get_span = Some(self.get_span.clone());
172 MakeFuture {
173 get_span,
174 inner,
175 _p: PhantomData,
176 }
177 }
178 }
179
180 impl<S, R, G> MakeService<S, R, G>
181 where
182 G: GetSpan<R> + Clone,
183 {
184 pub fn new<T>(inner: S, get_span: G) -> Self
185 where
186 S: tower_make::MakeService<T, R>,
187 {
188 Self {
189 get_span,
190 inner,
191 _p: PhantomData,
192 }
193 }
194 }
195
196 impl<S, R, G> Clone for MakeService<S, R, G>
197 where
198 G: GetSpan<R> + Clone,
199 S: Clone,
200 {
201 fn clone(&self) -> Self {
202 Self {
203 get_span: self.get_span.clone(),
204 inner: self.inner.clone(),
205 _p: PhantomData,
206 }
207 }
208 }
209
210 impl<F, R, G, S, E> Future for MakeFuture<F, R, G>
211 where
212 F: Future<Output = Result<S, E>>,
213 S: tower_service::Service<R>,
214 G: GetSpan<R> + Clone,
215 {
216 type Output = Result<Service<S, R, G>, E>;
217
218 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
219 let this = self.project();
220 let inner = futures::ready!(this.inner.poll(cx));
221 let get_span = this.get_span.take().expect("polled after ready");
222 Poll::Ready(inner.map(|inner| Service {
223 inner,
224 get_span,
225 _p: PhantomData,
226 }))
227 }
228 }
229}
230
231impl<S, R, G> tower_service::Service<R> for Service<S, R, G>
234where
235 S: tower_service::Service<R>,
236 G: GetSpan<R> + Clone,
237{
238 type Response = S::Response;
239 type Error = S::Error;
240 type Future = tracing::instrument::Instrumented<S::Future>;
241
242 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
243 self.inner.poll_ready(cx)
244 }
245
246 fn call(&mut self, request: R) -> Self::Future {
247 let span = self.get_span.span_for(&request);
248 let _enter = span.enter();
249 self.inner.call(request).instrument(span.clone())
250 }
251}
252
253impl<S, R, G> Clone for Service<S, R, G>
254where
255 S: tower_service::Service<R> + Clone,
256 G: GetSpan<R> + Clone,
257{
258 fn clone(&self) -> Self {
259 Service {
260 get_span: self.get_span.clone(),
261 inner: self.inner.clone(),
262 _p: PhantomData,
263 }
264 }
265}
266
267impl<S, R, G> Service<S, R, G>
268where
269 S: tower_service::Service<R>,
270 G: GetSpan<R> + Clone,
271{
272 pub fn new(inner: S, get_span: G) -> Self {
273 Service {
274 get_span,
275 inner,
276 _p: PhantomData,
277 }
278 }
279}