diff --git a/src/serde.rs b/src/serde.rs index efc9f14a4..50128330f 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -60,6 +60,17 @@ impl<'de> Deserialize<'de> for Level { self.visit_str(variant) } + + fn visit_u64(self, v: u64) -> Result + where + E: Error, + { + let variant = LOG_LEVEL_NAMES[1..] + .get(v as usize) + .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v), &self))?; + + self.visit_str(variant) + } } impl<'de> DeserializeSeed<'de> for LevelIdentifier { @@ -144,6 +155,17 @@ impl<'de> Deserialize<'de> for LevelFilter { self.visit_str(variant) } + + fn visit_u64(self, v: u64) -> Result + where + E: Error, + { + let variant = LOG_LEVEL_NAMES + .get(v as usize) + .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v), &self))?; + + self.visit_str(variant) + } } impl<'de> DeserializeSeed<'de> for LevelFilterIdentifier { @@ -203,6 +225,14 @@ mod tests { ] } + fn level_variant_tokens(variant: u32) -> [Token; 3] { + [ + Token::Enum { name: "Level" }, + Token::U32(variant), + Token::Unit, + ] + } + fn level_filter_token(variant: &'static str) -> Token { Token::UnitVariant { name: "LevelFilter", @@ -220,6 +250,16 @@ mod tests { ] } + fn level_filter_variant_tokens(variant: u32) -> [Token; 3] { + [ + Token::Enum { + name: "LevelFilter", + }, + Token::U32(variant), + Token::Unit, + ] + } + #[test] fn test_level_ser_de() { let cases = [ @@ -265,6 +305,21 @@ mod tests { } } + #[test] + fn test_level_de_variant_index() { + let cases = [ + (Level::Error, level_variant_tokens(0)), + (Level::Warn, level_variant_tokens(1)), + (Level::Info, level_variant_tokens(2)), + (Level::Debug, level_variant_tokens(3)), + (Level::Trace, level_variant_tokens(4)), + ]; + + for &(value, tokens) in &cases { + assert_de_tokens(&value, &tokens); + } + } + #[test] fn test_level_de_error() { let msg = "unknown variant `errorx`, expected one of \ @@ -320,6 +375,22 @@ mod tests { } } + #[test] + fn test_level_filter_de_variant_index() { + let cases = [ + (LevelFilter::Off, level_filter_variant_tokens(0)), + (LevelFilter::Error, level_filter_variant_tokens(1)), + (LevelFilter::Warn, level_filter_variant_tokens(2)), + (LevelFilter::Info, level_filter_variant_tokens(3)), + (LevelFilter::Debug, level_filter_variant_tokens(4)), + (LevelFilter::Trace, level_filter_variant_tokens(5)), + ]; + + for &(value, tokens) in &cases { + assert_de_tokens(&value, &tokens); + } + } + #[test] fn test_level_filter_de_error() { let msg = "unknown variant `errorx`, expected one of \