use std::str::FromStr; use serde::{Deserialize, Deserializer, Serialize}; use tracing::level_filters::LevelFilter; /// Logging settings #[derive(Debug, Clone, Serialize, Deserialize)] pub struct LogSettings { #[serde( deserialize_with = "deserialize_level_filter", serialize_with = "serialize_level_filter" )] pub level: LevelFilter, } impl Default for LogSettings { fn default() -> Self { Self { level: default_log_level(), } } } fn default_log_level() -> LevelFilter { LevelFilter::INFO } fn deserialize_level_filter<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; LevelFilter::from_str(&s).map_err(serde::de::Error::custom) } fn serialize_level_filter(level: &LevelFilter, serializer: S) -> Result where S: serde::Serializer, { serializer.serialize_str(&level.to_string()) } #[cfg(test)] mod tests { use super::*; #[test] fn test_esnure_send_and_sync() { fn assert_send_sync() {} assert_send_sync::(); } #[test] fn level_filter_round_trip_serialization() { #[derive(Serialize, Deserialize)] struct Wrapper { #[serde( deserialize_with = "deserialize_level_filter", serialize_with = "serialize_level_filter" )] level: LevelFilter, } let original = Wrapper { level: LevelFilter::DEBUG, }; let encoded = serde_json::to_string(&original); assert!(encoded.is_ok()); let encoded = encoded.ok(); assert!(encoded.is_some()); let encoded = encoded.unwrap_or_else(|| unreachable!()); assert!(encoded.to_lowercase().contains("debug")); let decoded = serde_json::from_str::(&encoded); assert!(decoded.is_ok()); let decoded = decoded.ok(); assert!(decoded.is_some()); let decoded = decoded.unwrap_or_else(|| unreachable!()); assert_eq!(decoded.level, LevelFilter::DEBUG); } }