1use tracing_core::{Event, Subscriber};
2use tracing_subscriber::{
3 fmt::{
4 format::{
5 Compact, DefaultFields, Format, Full, Json, JsonFields, Pretty, PrettyFields, Writer,
6 },
7 FmtContext,
8 },
9 registry::LookupSpan,
10};
11
12use crate::time::FormatTime;
13
14pub struct FormatEvent(FormatEventInner);
16
17impl From<crate::Format> for FormatEvent {
18 fn from(value: crate::Format) -> Self {
19 Self(value.into())
20 }
21}
22
23impl<S, N> tracing_subscriber::fmt::FormatEvent<S, N> for FormatEvent
24where
25 S: Subscriber + for<'a> LookupSpan<'a>,
26 N: for<'a> tracing_subscriber::fmt::FormatFields<'a> + 'static,
27{
28 fn format_event(
29 &self,
30 ctx: &FmtContext<'_, S, N>,
31 writer: Writer<'_>,
32 event: &Event<'_>,
33 ) -> std::fmt::Result {
34 self.0.format_event(ctx, writer, event)
35 }
36}
37
38pub struct FormatFields(FormatFieldsInner);
40
41impl From<crate::Formatter> for FormatFields {
42 fn from(value: crate::Formatter) -> Self {
43 Self(value.into())
44 }
45}
46
47impl<'writer> tracing_subscriber::fmt::FormatFields<'writer> for FormatFields {
48 fn format_fields<R: tracing_subscriber::field::RecordFields>(
49 &self,
50 writer: Writer<'writer>,
51 fields: R,
52 ) -> std::fmt::Result {
53 self.0.format_fields(writer, fields)
54 }
55}
56
57enum FormatEventInner {
58 Full(Format<Full, FormatTime>),
59 Compact(Format<Compact, FormatTime>),
60 Pretty(Format<Pretty, FormatTime>),
61 Json(Format<Json, FormatTime>),
62}
63
64impl From<crate::Format> for FormatEventInner {
65 fn from(value: crate::Format) -> Self {
66 let crate::Format {
67 ansi,
68 target,
69 level,
70 thread_ids,
71 thread_names,
72 file,
73 line_number,
74 formatter,
75 timer,
76 span_events: _, } = value;
78
79 let orig = Format::default().with_timer(FormatTime::from(timer.unwrap_or_default()));
80 let mut this = match formatter.unwrap_or_default() {
81 crate::Formatter::Full => Self::Full(orig),
82 crate::Formatter::Compact => Self::Compact(orig.compact()),
83 crate::Formatter::Pretty => Self::Pretty(orig.pretty()),
84 crate::Formatter::Json(it) => Self::Json({
85 let crate::Json {
86 flatten_event,
87 current_span,
88 span_list,
89 } = it.unwrap_or_default();
90 let mut this = orig.json();
91 if let Some(it) = flatten_event {
92 this = this.flatten_event(it)
93 }
94 if let Some(it) = current_span {
95 this = this.with_current_span(it)
96 }
97 if let Some(it) = span_list {
98 this = this.with_span_list(it)
99 }
100 this
101 }),
102 };
103
104 macro_rules! apply {
105 ($receiver:ident.$method:ident($arg:expr)) => {
106 if let Some(arg) = $arg {
107 $receiver = match $receiver {
108 Self::Full(it) => Self::Full(it.$method(arg)),
109 Self::Compact(it) => Self::Compact(it.$method(arg)),
110 Self::Pretty(it) => Self::Pretty(it.$method(arg)),
111 Self::Json(it) => Self::Json(it.$method(arg)),
112 };
113 }
114 };
115 }
116
117 apply!(this.with_ansi(ansi));
118 apply!(this.with_target(target));
119 apply!(this.with_level(level));
120 apply!(this.with_thread_ids(thread_ids));
121 apply!(this.with_thread_names(thread_names));
122 apply!(this.with_file(file));
123 apply!(this.with_line_number(line_number));
124
125 this
126 }
127}
128
129impl<S, N> tracing_subscriber::fmt::FormatEvent<S, N> for FormatEventInner
130where
131 S: Subscriber + for<'a> LookupSpan<'a>,
132 N: for<'a> tracing_subscriber::fmt::format::FormatFields<'a> + 'static,
133{
134 fn format_event(
135 &self,
136 ctx: &FmtContext<'_, S, N>,
137 writer: Writer<'_>,
138 event: &Event<'_>,
139 ) -> std::fmt::Result {
140 match self {
141 FormatEventInner::Full(it) => it.format_event(ctx, writer, event),
142 FormatEventInner::Compact(it) => it.format_event(ctx, writer, event),
143 FormatEventInner::Pretty(it) => it.format_event(ctx, writer, event),
144 FormatEventInner::Json(it) => it.format_event(ctx, writer, event),
145 }
146 }
147}
148
149enum FormatFieldsInner {
150 Default(DefaultFields),
151 Json(JsonFields),
152 Pretty(PrettyFields),
153}
154
155impl From<crate::Formatter> for FormatFieldsInner {
156 fn from(value: crate::Formatter) -> Self {
157 match value {
158 crate::Formatter::Full => Self::Default(DefaultFields::new()),
159 crate::Formatter::Compact => Self::Default(DefaultFields::new()),
160 crate::Formatter::Pretty => Self::Pretty(PrettyFields::new()),
161 crate::Formatter::Json { .. } => Self::Json(JsonFields::new()),
162 }
163 }
164}
165
166impl<'writer> tracing_subscriber::fmt::FormatFields<'writer> for FormatFieldsInner {
167 fn format_fields<R: tracing_subscriber::field::RecordFields>(
168 &self,
169 writer: Writer<'writer>,
170 fields: R,
171 ) -> std::fmt::Result {
172 match self {
173 FormatFieldsInner::Default(it) => it.format_fields(writer, fields),
174 FormatFieldsInner::Json(it) => it.format_fields(writer, fields),
175 FormatFieldsInner::Pretty(it) => it.format_fields(writer, fields),
176 }
177 }
178}