@@ -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,35 @@ 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
+ #[ allow( dead_code) ]
316
+ level : LevelFilter ,
317
+ }
318
+
319
+ for level in [ "off" , "trace" , "debug" , "info" , "warn" , "warning" , "error" ] {
320
+ let multi = level. chars ( ) . map ( |_| 0 ..=1 ) . multi_cartesian_product ( ) ;
321
+ for combination in multi {
322
+ let variant = level
323
+ . chars ( )
324
+ . zip_eq ( combination)
325
+ . map ( |( c, v) | match v {
326
+ 0 => c. to_ascii_lowercase ( ) ,
327
+ 1 => c. to_ascii_uppercase ( ) ,
328
+ _ => unreachable ! ( ) ,
329
+ } )
330
+ . collect :: < String > ( ) ;
331
+
332
+ let ex = format ! ( "{} \" level\" : \" {}\" {}" , "{" , variant, "}" ) ;
333
+ assert ! ( LevelFilter :: from_str( & variant) . is_ok( ) , "{variant}" ) ;
334
+ assert ! ( serde_json:: from_str:: <Foo >( & ex) . is_ok( ) , "{ex}" ) ;
335
+ }
336
+ }
337
+ }
338
+ #[ test]
291
339
fn levelfilter_from_str ( ) {
292
340
assert_eq ! (
293
341
LevelFilter :: from_str( "bad" ) ,
0 commit comments