#! [cfg(feature = "serde" )]
extern crate serde;
use self ::serde::de::{
Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, Unexpected, VariantAccess,
Visitor,
};
use self ::serde::ser::{Serialize, Serializer};
use {Level, LevelFilter, LOG_LEVEL_NAMES};
use std::fmt;
use std::str::{self , FromStr};
// The Deserialize impls are handwritten to be case insensitive using FromStr.
impl Serialize for Level {
fn serialize<S>(&self , serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self {
Level::Error => serializer.serialize_unit_variant("Level" , 0 , "ERROR" ),
Level::Warn => serializer.serialize_unit_variant("Level" , 1 , "WARN" ),
Level::Info => serializer.serialize_unit_variant("Level" , 2 , "INFO" ),
Level::Debug => serializer.serialize_unit_variant("Level" , 3 , "DEBUG" ),
Level::Trace => serializer.serialize_unit_variant("Level" , 4 , "TRACE" ),
}
}
}
impl <'de> Deserialize<' de> for Level {
fn deserialize<D>(deserializer: D) -> Result<Self , D::Error>
where
D: Deserializer<'de>,
{
struct LevelIdentifier;
impl <'de> Visitor<' de> for LevelIdentifier {
type Value = Level;
fn expecting(&self , formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("log level" )
}
fn visit_str<E>(self , s: &str) -> Result<Self ::Value, E>
where
E: Error,
{
// Case insensitive.
FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES[1 ..]))
}
fn visit_bytes<E>(self , value: &[u8]) -> Result<Self ::Value, E>
where
E: Error,
{
let variant = str::from_utf8(value)
.map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &>self ))?;
self .visit_str(variant)
}
fn visit_u64<E>(self , v: u64) -> Result<Self ::Value, E>
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 {
type Value = Level;
fn deserialize<D>(self , deserializer: D) -> Result<Self ::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_identifier(LevelIdentifier)
}
}
struct LevelEnum;
impl <'de> Visitor<' de> for LevelEnum {
type Value = Level;
fn expecting(&self , formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("log level" )
}
fn visit_enum<A>(self , value: A) -> Result<Self ::Value, A::Error>
where
A: EnumAccess<'de>,
{
let (level, variant) = value.variant_seed(LevelIdentifier)?;
// Every variant is a unit variant.
variant.unit_variant()?;
Ok(level)
}
}
deserializer.deserialize_enum("Level" , &LOG_LEVEL_NAMES[1 ..], LevelEnum)
}
}
impl Serialize for LevelFilter {
fn serialize<S>(&self , serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self {
LevelFilter::Off => serializer.serialize_unit_variant("LevelFilter" , 0 , "OFF" ),
LevelFilter::Error => serializer.serialize_unit_variant("LevelFilter" , 1 , "ERROR" ),
LevelFilter::Warn => serializer.serialize_unit_variant("LevelFilter" , 2 , "WARN" ),
LevelFilter::Info => serializer.serialize_unit_variant("LevelFilter" , 3 , "INFO" ),
LevelFilter::Debug => serializer.serialize_unit_variant("LevelFilter" , 4 , "DEBUG" ),
LevelFilter::Trace => serializer.serialize_unit_variant("LevelFilter" , 5 , "TRACE" ),
}
}
}
impl <'de> Deserialize<' de> for LevelFilter {
fn deserialize<D>(deserializer: D) -> Result<Self , D::Error>
where
D: Deserializer<'de>,
{
struct LevelFilterIdentifier;
impl <'de> Visitor<' de> for LevelFilterIdentifier {
type Value = LevelFilter;
fn expecting(&self , formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("log level filter" )
}
fn visit_str<E>(self , s: &str) -> Result<Self ::Value, E>
where
E: Error,
{
// Case insensitive.
FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES))
}
fn visit_bytes<E>(self , value: &[u8]) -> Result<Self ::Value, E>
where
E: Error,
{
let variant = str::from_utf8(value)
.map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &>self ))?;
self .visit_str(variant)
}
fn visit_u64<E>(self , v: u64) -> Result<Self ::Value, E>
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 {
type Value = LevelFilter;
fn deserialize<D>(self , deserializer: D) -> Result<Self ::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_identifier(LevelFilterIdentifier)
}
}
struct LevelFilterEnum;
impl <'de> Visitor<' de> for LevelFilterEnum {
type Value = LevelFilter;
fn expecting(&self , formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("log level filter" )
}
fn visit_enum<A>(self , value: A) -> Result<Self ::Value, A::Error>
where
A: EnumAccess<'de>,
{
let (level_filter, variant) = value.variant_seed(LevelFilterIdentifier)?;
// Every variant is a unit variant.
variant.unit_variant()?;
Ok(level_filter)
}
}
deserializer.deserialize_enum("LevelFilter" , &LOG_LEVEL_NAMES, LevelFilterEnum)
}
}
#[ cfg(test)]
mod tests {
extern crate serde_test;
use self ::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token};
use {Level, LevelFilter};
fn level_token(variant: &'static str) -> Token {
Token::UnitVariant {
name: "Level" ,
variant: variant,
}
}
fn level_bytes_tokens(variant: &'static [u8]) -> [Token; 3] {
[
Token::Enum { name: "Level" },
Token::Bytes(variant),
Token::Unit,
]
}
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" ,
variant: variant,
}
}
fn level_filter_bytes_tokens(variant: &'static [u8]) -> [Token; 3] {
[
Token::Enum {
name: "LevelFilter" ,
},
Token::Bytes(variant),
Token::Unit,
]
}
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 = [
(Level::Error, [level_token("ERROR" )]),
(Level::Warn, [level_token("WARN" )]),
(Level::Info, [level_token("INFO" )]),
(Level::Debug, [level_token("DEBUG" )]),
(Level::Trace, [level_token("TRACE" )]),
];
for &(s, expected) in &cases {
assert_tokens(&s, &expected);
}
}
#[ test]
fn test_level_case_insensitive() {
let cases = [
(Level::Error, [level_token("error" )]),
(Level::Warn, [level_token("warn" )]),
(Level::Info, [level_token("info" )]),
(Level::Debug, [level_token("debug" )]),
(Level::Trace, [level_token("trace" )]),
];
for &(s, expected) in &cases {
assert_de_tokens(&s, &expected);
}
}
#[ test]
fn test_level_de_bytes() {
let cases = [
(Level::Error, level_bytes_tokens(b"ERROR" )),
(Level::Warn, level_bytes_tokens(b"WARN" )),
(Level::Info, level_bytes_tokens(b"INFO" )),
(Level::Debug, level_bytes_tokens(b"DEBUG" )),
(Level::Trace, level_bytes_tokens(b"TRACE" )),
];
for &(value, tokens) in &cases {
assert_de_tokens(&value, &tokens);
}
}
#[ 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 \
`ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`";
assert_de_tokens_error::<Level>(&[level_token("errorx" )], msg);
}
#[ test]
fn test_level_filter_ser_de() {
let cases = [
(LevelFilter::Off, [level_filter_token("OFF" )]),
(LevelFilter::Error, [level_filter_token("ERROR" )]),
(LevelFilter::Warn, [level_filter_token("WARN" )]),
(LevelFilter::Info, [level_filter_token("INFO" )]),
(LevelFilter::Debug, [level_filter_token("DEBUG" )]),
(LevelFilter::Trace, [level_filter_token("TRACE" )]),
];
for &(s, expected) in &cases {
assert_tokens(&s, &expected);
}
}
#[ test]
fn test_level_filter_case_insensitive() {
let cases = [
(LevelFilter::Off, [level_filter_token("off" )]),
(LevelFilter::Error, [level_filter_token("error" )]),
(LevelFilter::Warn, [level_filter_token("warn" )]),
(LevelFilter::Info, [level_filter_token("info" )]),
(LevelFilter::Debug, [level_filter_token("debug" )]),
(LevelFilter::Trace, [level_filter_token("trace" )]),
];
for &(s, expected) in &cases {
assert_de_tokens(&s, &expected);
}
}
#[ test]
fn test_level_filter_de_bytes() {
let cases = [
(LevelFilter::Off, level_filter_bytes_tokens(b"OFF" )),
(LevelFilter::Error, level_filter_bytes_tokens(b"ERROR" )),
(LevelFilter::Warn, level_filter_bytes_tokens(b"WARN" )),
(LevelFilter::Info, level_filter_bytes_tokens(b"INFO" )),
(LevelFilter::Debug, level_filter_bytes_tokens(b"DEBUG" )),
(LevelFilter::Trace, level_filter_bytes_tokens(b"TRACE" )),
];
for &(value, tokens) in &cases {
assert_de_tokens(&value, &tokens);
}
}
#[ 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 \
`OFF`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`";
assert_de_tokens_error::<LevelFilter>(&[level_filter_token("errorx" )], msg);
}
}
Messung V0.5 in Prozent C=84 H=86 G=84
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-18)
¤
*© Formatika GbR, Deutschland