#![doc = include_str!("../README.md")]
#![cfg_attr(
feature = "docs",
cfg_attr(doc, doc = ::document_features::document_features!())
)]
#![cfg_attr(not(feature = "std"), no_std)]
use core::any::Any;
use core::fmt;
pub use tracing_wide_macros::{event, message};
#[cfg(doc)]
pub mod examples;
#[cfg(feature = "facet")]
pub use ::facet;
#[cfg(feature = "catalogue")]
pub mod catalogue;
#[cfg(feature = "instrument")]
pub mod instrument;
#[cfg(feature = "subscriber")]
pub mod subscriber;
pub trait Field: tracing::field::Value {}
pub trait Message: __private::MessageBehaviour {
fn as_any(&self) -> &dyn Any;
#[cfg(feature = "facet")]
fn as_facet(&self) -> Option<::facet::Peek<'_, 'static>> {
None
}
#[cfg(feature = "serde")]
fn as_serialize(&self) -> Option<&dyn ::erased_serde::Serialize> {
None
}
fn level(&self) -> tracing::Level;
fn msg(&self) -> &'static str;
fn origin(&self) -> &'static Origin;
fn tags(&self) -> &'static [&'static str] {
&[]
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "facet", derive(::facet::Facet))]
#[cfg_attr(feature = "facet", facet(proxy = String))]
pub struct Origin {
pub column: u32,
pub file: &'static str,
pub krate: &'static str,
pub line: u32,
pub module: &'static str,
}
impl fmt::Display for Origin {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{} {}:{}:{}",
self.krate, self.file, self.line, self.column
)
}
}
#[cfg(feature = "facet")]
#[allow(clippy::infallible_try_from)]
impl TryFrom<&Origin> for String {
type Error = core::convert::Infallible;
fn try_from(origin: &Origin) -> Result<Self, Self::Error> {
Ok(origin.to_string())
}
}
#[cfg(feature = "facet")]
impl TryFrom<String> for Origin {
type Error = &'static str;
fn try_from(_: String) -> Result<Self, Self::Error> {
Err("Origin is serialize-only in the catalogue")
}
}
impl<T: tracing::field::Value> Field for T {}
#[cfg(feature = "catalogue")]
#[doc(hidden)]
#[macro_export]
macro_rules! __register_message {
($desc:expr) => {
#[allow(deprecated)]
const _: () = {
$crate::__private::inventory::submit! { $desc }
};
};
}
#[cfg(not(feature = "catalogue"))]
#[doc(hidden)]
#[macro_export]
macro_rules! __register_message {
($desc:expr) => {};
}
#[cfg(feature = "facet")]
#[doc(hidden)]
#[macro_export]
macro_rules! __message_facet_method {
() => {
fn as_facet(&self) -> ::core::option::Option<$crate::__private::facet::Peek<'_, 'static>> {
#[allow(unused_imports)]
use $crate::__private::facet::{ViaFacet as _, ViaNotFacet as _};
(&$crate::__private::facet::Probe::new(self)).__tracing_wide_as_facet()
}
};
}
#[cfg(not(feature = "facet"))]
#[doc(hidden)]
#[macro_export]
macro_rules! __message_facet_method {
() => {};
}
#[cfg(feature = "instrument")]
#[doc(hidden)]
#[macro_export]
macro_rules! __message_ambient_method {
( $( ($field:ident, $ty:ty) ),* $(,)? ) => {
#[allow(deprecated)]
fn join_ambient(&mut self) {
$(
if self.$field.is_none() {
if let ::core::option::Option::Some(__tracing_wide_value) =
$crate::__private::instrument::get(::core::stringify!($field))
{
#[allow(unused_imports)]
use $crate::__private::instrument::{
ViaFromCaptured as _, ViaNotCapturable as _,
};
self.$field = (&$crate::__private::instrument::Probe::<$ty>::new())
.__tracing_wide_from_captured(&__tracing_wide_value);
}
}
)*
}
};
}
#[cfg(not(feature = "instrument"))]
#[doc(hidden)]
#[macro_export]
macro_rules! __message_ambient_method {
( $($tt:tt)* ) => {};
}
#[cfg(feature = "serde")]
#[doc(hidden)]
#[macro_export]
macro_rules! __message_serialize_method {
() => {
fn as_serialize(&self) -> ::core::option::Option<&dyn $crate::__private::serde::Serialize> {
#[allow(unused_imports)]
use $crate::__private::serde::{ViaNotSerializable as _, ViaSerialize as _};
(&$crate::__private::serde::Probe::new(self)).__tracing_wide_as_serialize()
}
};
}
#[cfg(not(feature = "serde"))]
#[doc(hidden)]
#[macro_export]
macro_rules! __message_serialize_method {
() => {};
}
#[doc(hidden)]
pub mod __private {
#[cfg(feature = "catalogue")]
pub use ::inventory;
pub use ::tracing;
pub trait MessageBehaviour: Sealed {
fn emit(&self)
where
Self: crate::Message + Sized,
{
#[cfg(feature = "subscriber")]
crate::subscriber::dispatch(self);
self.record();
}
fn join_ambient(&mut self) {}
fn record(&self);
}
pub trait Sealed {}
#[cfg(feature = "facet")]
pub mod facet {
use ::facet::Facet;
pub use ::facet::Peek;
pub struct Probe<'a, T>(&'a T);
pub trait ViaFacet<'a> {
fn __tracing_wide_as_facet(&self) -> Option<Peek<'a, 'static>>;
}
pub trait ViaNotFacet<'a> {
fn __tracing_wide_as_facet(&self) -> Option<Peek<'a, 'static>>;
}
impl<'a, T> Probe<'a, T> {
pub fn new(value: &'a T) -> Self {
Probe(value)
}
}
impl<'a, T: Facet<'static>> ViaFacet<'a> for Probe<'a, T> {
fn __tracing_wide_as_facet(&self) -> Option<Peek<'a, 'static>> {
Some(Peek::new(self.0))
}
}
impl<'a, T> ViaNotFacet<'a> for &Probe<'a, T> {
fn __tracing_wide_as_facet(&self) -> Option<Peek<'a, 'static>> {
None
}
}
}
#[cfg(feature = "instrument")]
pub mod instrument {
use core::marker::PhantomData;
use tracing::{Span, dispatcher};
use tracing_subscriber::registry::{LookupSpan, Registry};
use crate::instrument::{CapturedFields, CapturedValue, FromCaptured};
pub struct Probe<T>(PhantomData<T>);
pub trait ViaFromCaptured<T> {
fn __tracing_wide_from_captured(&self, value: &CapturedValue) -> Option<T>;
}
pub trait ViaNotCapturable<T> {
fn __tracing_wide_from_captured(&self, value: &CapturedValue) -> Option<T>;
}
impl<T> Probe<T> {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Probe(PhantomData)
}
}
impl<T: FromCaptured> ViaFromCaptured<T> for Probe<T> {
fn __tracing_wide_from_captured(&self, value: &CapturedValue) -> Option<T> {
T::from_captured(value)
}
}
impl<T> ViaNotCapturable<T> for &Probe<T> {
fn __tracing_wide_from_captured(&self, _: &CapturedValue) -> Option<T> {
None
}
}
pub fn get(name: &str) -> Option<CapturedValue> {
let current = Span::current();
let id = current.id()?;
dispatcher::get_default(|dispatch| {
let registry = dispatch.downcast_ref::<Registry>()?;
let span = registry.span(&id)?;
for span in span.scope() {
if let Some(captured) = span.extensions().get::<CapturedFields>()
&& let Some((_, value)) = captured.0.iter().find(|(n, _)| *n == name)
{
return Some(value.clone());
}
}
None
})
}
}
#[cfg(feature = "serde")]
pub mod serde {
pub use ::erased_serde::Serialize;
pub struct Probe<'a, T>(&'a T);
pub trait ViaNotSerializable<'a> {
fn __tracing_wide_as_serialize(&self) -> Option<&'a dyn Serialize>;
}
pub trait ViaSerialize<'a> {
fn __tracing_wide_as_serialize(&self) -> Option<&'a dyn Serialize>;
}
impl<'a, T> Probe<'a, T> {
pub fn new(value: &'a T) -> Self {
Probe(value)
}
}
impl<'a, T> ViaNotSerializable<'a> for &Probe<'a, T> {
fn __tracing_wide_as_serialize(&self) -> Option<&'a dyn Serialize> {
None
}
}
impl<'a, T: ::serde::Serialize> ViaSerialize<'a> for Probe<'a, T> {
fn __tracing_wide_as_serialize(&self) -> Option<&'a dyn Serialize> {
Some(self.0)
}
}
}
}