1use serde::{Deserialize, Serializer, de};
13use std::fmt::Formatter;
14use std::str::FromStr;
15use tracing_subscriber::EnvFilter;
16
17pub mod params;
18
19#[derive(Debug, Clone)]
20struct ValidatedEnvFilterString(String);
21
22pub struct CloneableEnvFilter {
24 filter: EnvFilter,
25 validated: ValidatedEnvFilterString,
26}
27
28impl AsRef<EnvFilter> for CloneableEnvFilter {
29 fn as_ref(&self) -> &EnvFilter {
30 &self.filter
31 }
32}
33
34impl From<CloneableEnvFilter> for EnvFilter {
35 fn from(value: CloneableEnvFilter) -> Self {
36 value.filter
37 }
38}
39
40impl PartialEq for CloneableEnvFilter {
41 fn eq(&self, other: &Self) -> bool {
42 format!("{}", self) == format!("{}", other)
43 }
44}
45
46impl Eq for CloneableEnvFilter {}
47
48impl Clone for CloneableEnvFilter {
49 fn clone(&self) -> Self {
50 Self {
52 filter: EnvFilter::from_str(&self.validated.0).expect("validated"),
56 validated: self.validated.clone(),
57 }
58 }
59}
60
61impl FromStr for CloneableEnvFilter {
62 type Err = tracing_subscriber::filter::ParseError;
63
64 fn from_str(s: &str) -> Result<Self, Self::Err> {
65 let filter: EnvFilter = s.parse()?;
66 Ok(CloneableEnvFilter {
67 filter,
68 validated: ValidatedEnvFilterString(s.to_string()),
69 })
70 }
71}
72
73impl std::fmt::Display for CloneableEnvFilter {
74 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
75 write!(f, "{}", self.filter)
76 }
77}
78
79impl std::fmt::Debug for CloneableEnvFilter {
80 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
81 write!(f, "{}", self.filter)
82 }
83}
84
85impl serde::Serialize for CloneableEnvFilter {
86 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
87 where
88 S: Serializer,
89 {
90 serializer.serialize_str(&format!("{}", self))
91 }
92}
93
94impl<'de> Deserialize<'de> for CloneableEnvFilter {
95 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
96 where
97 D: serde::Deserializer<'de>,
98 {
99 let s = String::deserialize(deserializer)?;
100 Self::from_str(s.as_str()).map_err(|x| de::Error::custom(x.to_string()))
101 }
102}
103use tracing_subscriber::filter::Directive;
104
105#[derive(PartialEq, Eq, Clone, Debug)]
107pub struct SerializableDirective(Directive);
108
109impl From<SerializableDirective> for Directive {
110 fn from(value: SerializableDirective) -> Self {
111 value.0
112 }
113}
114
115impl From<Directive> for SerializableDirective {
116 fn from(value: Directive) -> Self {
117 SerializableDirective(value)
118 }
119}
120
121impl FromStr for SerializableDirective {
122 type Err = tracing_subscriber::filter::ParseError;
123
124 fn from_str(s: &str) -> Result<Self, Self::Err> {
125 let dir: Directive = s.parse()?;
126 Ok(SerializableDirective(dir))
127 }
128}
129
130impl std::fmt::Display for SerializableDirective {
131 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
132 write!(f, "{}", self.0)
133 }
134}
135
136impl serde::Serialize for SerializableDirective {
137 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
138 where
139 S: Serializer,
140 {
141 serializer.serialize_str(&format!("{}", self))
142 }
143}
144
145impl<'de> Deserialize<'de> for SerializableDirective {
146 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
147 where
148 D: serde::Deserializer<'de>,
149 {
150 let s = String::deserialize(deserializer)?;
151 Self::from_str(s.as_str()).map_err(|x| de::Error::custom(x.to_string()))
152 }
153}
154
155#[cfg(test)]
156mod test {
157 use crate::{CloneableEnvFilter, SerializableDirective};
158 use std::str::FromStr;
159
160 #[mz_ore::test]
164 fn roundtrips() {
165 let filter = CloneableEnvFilter::from_str(
166 "abc=debug,def=trace,[123],foo,baz[bar{a=b}]=debug,[{13=37}]=trace,info",
167 )
168 .expect("valid");
169 assert_eq!(
170 format!("{}", filter),
171 format!(
172 "{}",
173 CloneableEnvFilter::from_str(&format!("{}", filter)).expect("valid")
174 )
175 );
176 }
177
178 #[mz_ore::test]
179 fn roundtrips_directive() {
180 let dir = SerializableDirective::from_str("abc=debug").expect("valid");
181 assert_eq!(
182 format!("{}", dir),
183 format!(
184 "{}",
185 SerializableDirective::from_str(&format!("{}", dir)).expect("valid")
186 )
187 );
188 }
189}