//! Utilities for working with [fields] and [field visitors]. //! //! [fields]: tracing_core::field //! [field visitors]: tracing_core::field::Visit use core::{fmt, marker::PhantomData}; pubuse tracing_core::field::Visit; use tracing_core::{
span::{Attributes, Record},
Event,
}; pubmod debug; pubmod delimited; pubmod display;
/// Creates new [visitors]. /// /// A type implementing `MakeVisitor` represents a composable factory for types /// implementing the [`Visit` trait][visitors]. The `MakeVisitor` trait defines /// a single function, `make_visitor`, which takes in a `T`-typed `target` and /// returns a type implementing `Visit` configured for that target. A target may /// be a string, output stream, or data structure that the visitor will record /// data to, configuration variables that determine the visitor's behavior, or /// `()` when no input is required to produce a visitor. /// /// [visitors]: tracing_core::field::Visit pubtrait MakeVisitor<T> { /// The visitor type produced by this `MakeVisitor`. type Visitor: Visit;
/// Make a new visitor for the provided `target`. fn make_visitor(&self, target: T) -> Self::Visitor;
}
/// A [visitor] that produces output once it has visited a set of fields. /// /// [visitor]: tracing_core::field::Visit pubtrait VisitOutput<Out>: Visit { /// Completes the visitor, returning any output. /// /// This is called once a full set of fields has been visited. fn finish(self) -> Out;
/// Visit a set of fields, and return the output of finishing the visitor /// once the fields have been visited. fn visit<R>(mutself, fields: &R) -> Out where
R: RecordFields, Self: Sized,
{
fields.record(&mutself); self.finish()
}
}
/// Extension trait implemented by types which can be recorded by a [visitor]. /// /// This allows writing code that is generic over `tracing_core`'s /// [`span::Attributes`][attr], [`span::Record`][rec], and [`Event`] /// types. These types all provide inherent `record` methods that allow a /// visitor to record their fields, but there is no common trait representing this. /// /// With `RecordFields`, we can write code like this: /// ``` /// use tracing_core::field::Visit; /// # use tracing_core::field::Field; /// use tracing_subscriber::field::RecordFields; /// /// struct MyVisitor { /// // ... /// } /// # impl MyVisitor { fn new() -> Self { Self{} } } /// impl Visit for MyVisitor { /// // ... /// # fn record_debug(&mut self, _: &Field, _: &dyn std::fmt::Debug) {} /// } /// /// fn record_with_my_visitor<R>(r: R) /// where /// R: RecordFields, /// { /// let mut visitor = MyVisitor::new(); /// r.record(&mut visitor); /// } /// ``` /// [visitor]: tracing_core::field::Visit /// [attr]: tracing_core::span::Attributes /// [rec]: tracing_core::span::Record pubtrait RecordFields: crate::sealed::Sealed<RecordFieldsMarker> { /// Record all the fields in `self` with the provided `visitor`. fn record(&self, visitor: &mutdyn Visit);
}
/// Extension trait implemented for all `MakeVisitor` implementations that /// produce a visitor implementing `VisitOutput`. pubtrait MakeOutput<T, Out> where Self: MakeVisitor<T> + crate::sealed::Sealed<(T, Out)>, Self::Visitor: VisitOutput<Out>,
{ /// Visits all fields in `fields` with a new visitor constructed from /// `target`. fn visit_with<F>(&self, target: T, fields: &F) -> Out where
F: RecordFields,
{ self.make_visitor(target).visit(fields)
}
}
feature! { #![feature = "std"] use std::io;
/// Extension trait implemented by visitors to indicate that they write to an /// `io::Write` instance, and allow access to that writer. pubtrait VisitWrite: VisitOutput<Result<(), io::Error>> { /// Returns the writer that this visitor writes to. fn writer(&mutself) -> &mutdyn io::Write;
}
}
/// Extension trait implemented by visitors to indicate that they write to a /// `fmt::Write` instance, and allow access to that writer. pubtrait VisitFmt: VisitOutput<fmt::Result> { /// Returns the formatter that this visitor writes to. fn writer(&mutself) -> &mutdyn fmt::Write;
}
/// Extension trait providing `MakeVisitor` combinators. pubtrait MakeExt<T> where Self: MakeVisitor<T> + Sized, Self: crate::sealed::Sealed<MakeExtMarker<T>>,
{ /// Wraps `self` so that any `fmt::Debug` fields are recorded using the /// alternate formatter (`{:#?}`). fn debug_alt(self) -> debug::Alt<Self> {
debug::Alt::new(self)
}
/// Wraps `self` so that any string fields named "message" are recorded /// using `fmt::Display`. fn display_messages(self) -> display::Messages<Self> {
display::Messages::new(self)
}
/// Wraps `self` so that when fields are formatted to a writer, they are /// separated by the provided `delimiter`. fn delimited<D>(self, delimiter: D) -> delimited::Delimited<D, Self> where
D: AsRef<str> + Clone, Self::Visitor: VisitFmt,
{
delimited::Delimited::new(delimiter, self)
}
}
// === impl RecordFields ===
implcrate::sealed::Sealed<RecordFieldsMarker> for Event<'_> {} impl RecordFields for Event<'_> { fn record(&self, visitor: &mutdyn Visit) {
Event::record(self, visitor)
}
}
implcrate::sealed::Sealed<RecordFieldsMarker> for Attributes<'_> {} impl RecordFields for Attributes<'_> { fn record(&self, visitor: &mutdyn Visit) {
Attributes::record(self, visitor)
}
}
implcrate::sealed::Sealed<RecordFieldsMarker> for Record<'_> {} impl RecordFields for Record<'_> { fn record(&self, visitor: &mutdyn Visit) {
Record::record(self, visitor)
}
}
impl<F> crate::sealed::Sealed<RecordFieldsMarker> for &F where F: RecordFields {} impl<F> RecordFields for &F where
F: RecordFields,
{ fn record(&self, visitor: &mutdyn Visit) {
F::record(*self, visitor)
}
}
// === blanket impls ===
impl<T, V, F> MakeVisitor<T> for F where
F: Fn(T) -> V,
V: Visit,
{ type Visitor = V; fn make_visitor(&self, target: T) -> Self::Visitor {
(self)(target)
}
}
impl<T, Out, M> crate::sealed::Sealed<(T, Out)> for M where
M: MakeVisitor<T>,
M::Visitor: VisitOutput<Out>,
{
}
impl<T, Out, M> MakeOutput<T, Out> for M where
M: MakeVisitor<T>,
M::Visitor: VisitOutput<Out>,
{
}
impl<T, M> crate::sealed::Sealed<MakeExtMarker<T>> for M where M: MakeVisitor<T> + Sized {}
impl<T, M> MakeExt<T> for M where
M: MakeVisitor<T> + Sized,
M: crate::sealed::Sealed<MakeExtMarker<T>>,
{
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.