diff --git a/tokio-trace/src/span.rs b/tokio-trace/src/span.rs index 822fa6207..3232b26ad 100644 --- a/tokio-trace/src/span.rs +++ b/tokio-trace/src/span.rs @@ -126,12 +126,16 @@ pub use tokio_trace_core::span::{Attributes, Id, Record}; use std::{ - borrow::Borrow, cmp, fmt, hash::{Hash, Hasher}, }; use {dispatcher::Dispatch, field, Metadata}; +/// Trait implemented by types which have a span `Id`. +pub trait AsId: ::sealed::Sealed { + fn as_id(&self) -> Option<&Id>; +} + /// A handle representing a span, with the capability to enter the span if it /// exists. /// @@ -229,10 +233,10 @@ impl Span { values: &field::ValueSet, ) -> Span where - I: Into>, + I: AsId, { - let new_span = match parent.into() { - Some(parent) => Attributes::child_of(parent, meta, values), + let new_span = match parent.as_id() { + Some(parent) => Attributes::child_of(parent.clone(), meta, values), None => Attributes::new_root(meta, values), }; Self::make(meta, new_span) @@ -280,22 +284,21 @@ impl Span { /// Returns a [`Field`](::field::Field) for the field with the given `name`, if /// one exists, - pub fn field(&self, name: &Q) -> Option + pub fn field(&self, field: &Q) -> Option where - Q: Borrow, + Q: field::AsField, { - self.metadata().and_then(|meta| meta.fields().field(name)) + self.metadata().and_then(|meta| field.as_field(meta)) } /// Returns true if this `Span` has a field for the given /// [`Field`](::field::Field) or field name. + #[inline] pub fn has_field(&self, field: &Q) -> bool where Q: field::AsField, { - self.metadata() - .and_then(|meta| field.as_field(meta)) - .is_some() + self.field(field).is_some() } /// Visits that the field described by `field` has the value `value`. @@ -347,9 +350,14 @@ impl Span { /// /// If this span is disabled, or the resulting follows-from relationship /// would be invalid, this function will do nothing. - pub fn follows_from(&self, from: &Id) -> &Self { + pub fn follows_from(&self, from: I) -> &Self + where + I: AsId, + { if let Some(ref inner) = self.inner { - inner.follows_from(from); + if let Some(from) = from.as_id() { + inner.follows_from(from); + } } self } @@ -436,12 +444,6 @@ impl fmt::Debug for Span { } } -impl<'a> Into> for &'a Span { - fn into(self) -> Option { - self.id() - } -} - // ===== impl Inner ===== impl Inner { @@ -553,3 +555,53 @@ impl<'a> fmt::Display for FmtAttrs<'a> { res } } + +// ===== impl AsId ===== + +impl ::sealed::Sealed for Span {} + +impl AsId for Span { + fn as_id(&self) -> Option<&Id> { + self.inner.as_ref().map(|inner| &inner.id) + } +} + +impl<'a> ::sealed::Sealed for &'a Span {} + +impl<'a> AsId for &'a Span { + fn as_id(&self) -> Option<&Id> { + self.inner.as_ref().map(|inner| &inner.id) + } +} + +impl ::sealed::Sealed for Id {} + +impl AsId for Id { + fn as_id(&self) -> Option<&Id> { + Some(self) + } +} + +impl<'a> ::sealed::Sealed for &'a Id {} + +impl<'a> AsId for &'a Id { + fn as_id(&self) -> Option<&Id> { + Some(self) + } +} + +impl ::sealed::Sealed for Option {} + +impl AsId for Option { + fn as_id(&self) -> Option<&Id> { + self.as_ref() + } +} + +impl<'a> ::sealed::Sealed for &'a Option {} + +impl<'a> AsId for &'a Option { + fn as_id(&self) -> Option<&Id> { + self.as_ref() + } +}