@@ -10,7 +10,7 @@ use std::sync::{Mutex, OnceLock};
10
10
use std:: thread;
11
11
12
12
use log:: { Log , Metadata , Record } ;
13
- use serde:: { Deserialize , Serialize } ;
13
+ use serde:: { Deserialize , Deserializer , Serialize } ;
14
14
use utils:: time:: LocalTime ;
15
15
16
16
use super :: metrics:: { IncMetric , METRICS } ;
@@ -200,7 +200,7 @@ pub struct LoggerConfig {
200
200
/// the log level filter. It would be a breaking change to no longer support this. In the next
201
201
/// breaking release this should be removed (replaced with `log::LevelFilter` and only supporting
202
202
/// its default deserialization).
203
- #[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
203
+ #[ derive( Clone , Debug , PartialEq , Eq , Serialize ) ]
204
204
pub enum LevelFilter {
205
205
/// [`log::LevelFilter:Off`]
206
206
#[ serde( alias = "OFF" ) ]
@@ -233,6 +233,25 @@ impl From<LevelFilter> for log::LevelFilter {
233
233
}
234
234
}
235
235
}
236
+ impl < ' de > Deserialize < ' de > for LevelFilter {
237
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
238
+ where
239
+ D : Deserializer < ' de > ,
240
+ {
241
+ use serde:: de:: Error ;
242
+ let key = String :: deserialize ( deserializer) ?;
243
+ let level = match key. to_lowercase ( ) . as_str ( ) {
244
+ "off" => Ok ( LevelFilter :: Off ) ,
245
+ "trace" => Ok ( LevelFilter :: Trace ) ,
246
+ "debug" => Ok ( LevelFilter :: Debug ) ,
247
+ "info" => Ok ( LevelFilter :: Info ) ,
248
+ "warn" | "warning" => Ok ( LevelFilter :: Warn ) ,
249
+ "error" => Ok ( LevelFilter :: Error ) ,
250
+ _ => Err ( D :: Error :: custom ( "Invalid LevelFilter" ) ) ,
251
+ } ;
252
+ level
253
+ }
254
+ }
236
255
237
256
/// Error type for [`<LevelFilter as FromStr>::from_str`].
238
257
#[ derive( Debug , PartialEq , Eq , thiserror:: Error ) ]
@@ -288,6 +307,34 @@ mod tests {
288
307
) ;
289
308
}
290
309
#[ test]
310
+ fn levelfilter_from_str_all_variants ( ) {
311
+ use itertools:: Itertools ;
312
+
313
+ #[ derive( Debug , Deserialize ) ]
314
+ struct Foo {
315
+ level : LevelFilter ,
316
+ }
317
+
318
+ for level in [ "off" , "trace" , "debug" , "info" , "warn" , "warning" , "error" ] {
319
+ let multi = level. chars ( ) . map ( |_| 0 ..=1 ) . multi_cartesian_product ( ) ;
320
+ for combination in multi {
321
+ let variant = level
322
+ . chars ( )
323
+ . zip_eq ( combination)
324
+ . map ( |( c, v) | match v {
325
+ 0 => c. to_ascii_lowercase ( ) ,
326
+ 1 => c. to_ascii_uppercase ( ) ,
327
+ _ => unreachable ! ( ) ,
328
+ } )
329
+ . collect :: < String > ( ) ;
330
+
331
+ let ex = format ! ( "{} \" level\" : \" {}\" {}" , "{" , variant, "}" ) ;
332
+ assert ! ( LevelFilter :: from_str( & variant) . is_ok( ) , "{variant}" ) ;
333
+ assert ! ( serde_json:: from_str:: <Foo >( & ex) . is_ok( ) , "{ex}" ) ;
334
+ }
335
+ }
336
+ }
337
+ #[ test]
291
338
fn levelfilter_from_str ( ) {
292
339
assert_eq ! (
293
340
LevelFilter :: from_str( "bad" ) ,
0 commit comments