1use crate::{
2 dispatcher::{self, Dispatch},
3 span::Span,
4};
5use core::{
6 future::Future,
7 marker::Sized,
8 mem::ManuallyDrop,
9 pin::Pin,
10 task::{Context, Poll},
11};
12use pin_project_lite::pin_project;
13
14pub trait Instrument: Sized {
21 fn instrument(self, span: Span) -> Instrumented<Self> {
87 Instrumented {
88 inner: ManuallyDrop::new(self),
89 span,
90 }
91 }
92
93 #[inline]
128 fn in_current_span(self) -> Instrumented<Self> {
129 self.instrument(Span::current())
130 }
131}
132
133#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
136pub trait WithSubscriber: Sized {
137 fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
177 where
178 S: Into<Dispatch>,
179 {
180 WithDispatch {
181 inner: self,
182 dispatcher: subscriber.into(),
183 }
184 }
185
186 #[inline]
228 fn with_current_subscriber(self) -> WithDispatch<Self> {
229 WithDispatch {
230 inner: self,
231 dispatcher: crate::dispatcher::get_default(|default| default.clone()),
232 }
233 }
234}
235
236pin_project! {
237 #[derive(Clone, Debug)]
245 #[must_use = "futures do nothing unless you `.await` or poll them"]
246 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
247 pub struct WithDispatch<T> {
248 #[pin]
249 inner: T,
250 dispatcher: Dispatch,
251 }
252}
253
254pin_project! {
255 #[project = InstrumentedProj]
263 #[project_ref = InstrumentedProjRef]
264 #[derive(Debug, Clone)]
265 #[must_use = "futures do nothing unless you `.await` or poll them"]
266 pub struct Instrumented<T> {
267 #[pin]
270 inner: ManuallyDrop<T>,
271 span: Span,
272 }
273
274 impl<T> PinnedDrop for Instrumented<T> {
275 fn drop(this: Pin<&mut Self>) {
276 let this = this.project();
277 let _enter = this.span.enter();
278 unsafe { ManuallyDrop::drop(this.inner.get_unchecked_mut()) }
286 }
287 }
288}
289
290impl<'a, T> InstrumentedProj<'a, T> {
291 fn span_and_inner_pin_mut(self) -> (&'a mut Span, Pin<&'a mut T>) {
294 let inner = unsafe { self.inner.map_unchecked_mut(|v| &mut **v) };
298 (self.span, inner)
299 }
300}
301
302impl<'a, T> InstrumentedProjRef<'a, T> {
303 fn span_and_inner_pin_ref(self) -> (&'a Span, Pin<&'a T>) {
305 let inner = unsafe { self.inner.map_unchecked(|v| &**v) };
309 (self.span, inner)
310 }
311}
312
313impl<T: Future> Future for Instrumented<T> {
316 type Output = T::Output;
317
318 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
319 let (span, inner) = self.project().span_and_inner_pin_mut();
320 let _enter = span.enter();
321 inner.poll(cx)
322 }
323}
324
325impl<T: Sized> Instrument for T {}
326
327impl<T> Instrumented<T> {
328 pub fn span(&self) -> &Span {
330 &self.span
331 }
332
333 pub fn span_mut(&mut self) -> &mut Span {
335 &mut self.span
336 }
337
338 pub fn inner(&self) -> &T {
340 &self.inner
341 }
342
343 pub fn inner_mut(&mut self) -> &mut T {
345 &mut self.inner
346 }
347
348 pub fn inner_pin_ref(self: Pin<&Self>) -> Pin<&T> {
350 self.project_ref().span_and_inner_pin_ref().1
351 }
352
353 pub fn inner_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
355 self.project().span_and_inner_pin_mut().1
356 }
357
358 pub fn into_inner(self) -> T {
362 let this = ManuallyDrop::new(self);
365 let span: *const Span = &this.span;
366 let inner: *const ManuallyDrop<T> = &this.inner;
367 let _span = unsafe { span.read() };
371 let inner = unsafe { inner.read() };
372 ManuallyDrop::into_inner(inner)
373 }
374}
375
376#[cfg(feature = "std")]
379#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
380impl<T: Future> Future for WithDispatch<T> {
381 type Output = T::Output;
382
383 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
384 let this = self.project();
385 let dispatcher = this.dispatcher;
386 let future = this.inner;
387 let _default = dispatcher::set_default(dispatcher);
388 future.poll(cx)
389 }
390}
391
392#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
393impl<T: Sized> WithSubscriber for T {}
394
395#[cfg(feature = "std")]
396#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
397impl<T> WithDispatch<T> {
398 pub fn dispatcher(&self) -> &Dispatch {
400 &self.dispatcher
401 }
402
403 pub fn inner(&self) -> &T {
405 &self.inner
406 }
407
408 pub fn inner_mut(&mut self) -> &mut T {
410 &mut self.inner
411 }
412
413 pub fn inner_pin_ref(self: Pin<&Self>) -> Pin<&T> {
415 self.project_ref().inner
416 }
417
418 pub fn inner_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
420 self.project().inner
421 }
422
423 pub fn into_inner(self) -> T {
427 self.inner
428 }
429}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4