1 #![cfg(feature = "serde")] 2 3 extern crate serde; 4 use self::serde::de::{ 5 Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, Unexpected, VariantAccess, 6 Visitor, 7 }; 8 use self::serde::ser::{Serialize, Serializer}; 9 10 use {Level, LevelFilter, LOG_LEVEL_NAMES}; 11 12 use std::fmt; 13 use std::str::{self, FromStr}; 14 15 // The Deserialize impls are handwritten to be case insensitive using FromStr. 16 17 impl Serialize for Level { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,18 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 19 where 20 S: Serializer, 21 { 22 match *self { 23 Level::Error => serializer.serialize_unit_variant("Level", 0, "ERROR"), 24 Level::Warn => serializer.serialize_unit_variant("Level", 1, "WARN"), 25 Level::Info => serializer.serialize_unit_variant("Level", 2, "INFO"), 26 Level::Debug => serializer.serialize_unit_variant("Level", 3, "DEBUG"), 27 Level::Trace => serializer.serialize_unit_variant("Level", 4, "TRACE"), 28 } 29 } 30 } 31 32 impl<'de> Deserialize<'de> for Level { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,33 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 34 where 35 D: Deserializer<'de>, 36 { 37 struct LevelIdentifier; 38 39 impl<'de> Visitor<'de> for LevelIdentifier { 40 type Value = Level; 41 42 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 43 formatter.write_str("log level") 44 } 45 46 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> 47 where 48 E: Error, 49 { 50 // Case insensitive. 51 FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES[1..])) 52 } 53 54 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> 55 where 56 E: Error, 57 { 58 let variant = str::from_utf8(value) 59 .map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &self))?; 60 61 self.visit_str(variant) 62 } 63 64 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> 65 where 66 E: Error, 67 { 68 let variant = LOG_LEVEL_NAMES[1..] 69 .get(v as usize) 70 .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v), &self))?; 71 72 self.visit_str(variant) 73 } 74 } 75 76 impl<'de> DeserializeSeed<'de> for LevelIdentifier { 77 type Value = Level; 78 79 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> 80 where 81 D: Deserializer<'de>, 82 { 83 deserializer.deserialize_identifier(LevelIdentifier) 84 } 85 } 86 87 struct LevelEnum; 88 89 impl<'de> Visitor<'de> for LevelEnum { 90 type Value = Level; 91 92 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 93 formatter.write_str("log level") 94 } 95 96 fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error> 97 where 98 A: EnumAccess<'de>, 99 { 100 let (level, variant) = value.variant_seed(LevelIdentifier)?; 101 // Every variant is a unit variant. 102 variant.unit_variant()?; 103 Ok(level) 104 } 105 } 106 107 deserializer.deserialize_enum("Level", &LOG_LEVEL_NAMES[1..], LevelEnum) 108 } 109 } 110 111 impl Serialize for LevelFilter { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,112 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 113 where 114 S: Serializer, 115 { 116 match *self { 117 LevelFilter::Off => serializer.serialize_unit_variant("LevelFilter", 0, "OFF"), 118 LevelFilter::Error => serializer.serialize_unit_variant("LevelFilter", 1, "ERROR"), 119 LevelFilter::Warn => serializer.serialize_unit_variant("LevelFilter", 2, "WARN"), 120 LevelFilter::Info => serializer.serialize_unit_variant("LevelFilter", 3, "INFO"), 121 LevelFilter::Debug => serializer.serialize_unit_variant("LevelFilter", 4, "DEBUG"), 122 LevelFilter::Trace => serializer.serialize_unit_variant("LevelFilter", 5, "TRACE"), 123 } 124 } 125 } 126 127 impl<'de> Deserialize<'de> for LevelFilter { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,128 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 129 where 130 D: Deserializer<'de>, 131 { 132 struct LevelFilterIdentifier; 133 134 impl<'de> Visitor<'de> for LevelFilterIdentifier { 135 type Value = LevelFilter; 136 137 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 138 formatter.write_str("log level filter") 139 } 140 141 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> 142 where 143 E: Error, 144 { 145 // Case insensitive. 146 FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES)) 147 } 148 149 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> 150 where 151 E: Error, 152 { 153 let variant = str::from_utf8(value) 154 .map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &self))?; 155 156 self.visit_str(variant) 157 } 158 159 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> 160 where 161 E: Error, 162 { 163 let variant = LOG_LEVEL_NAMES 164 .get(v as usize) 165 .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v), &self))?; 166 167 self.visit_str(variant) 168 } 169 } 170 171 impl<'de> DeserializeSeed<'de> for LevelFilterIdentifier { 172 type Value = LevelFilter; 173 174 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> 175 where 176 D: Deserializer<'de>, 177 { 178 deserializer.deserialize_identifier(LevelFilterIdentifier) 179 } 180 } 181 182 struct LevelFilterEnum; 183 184 impl<'de> Visitor<'de> for LevelFilterEnum { 185 type Value = LevelFilter; 186 187 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 188 formatter.write_str("log level filter") 189 } 190 191 fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error> 192 where 193 A: EnumAccess<'de>, 194 { 195 let (level_filter, variant) = value.variant_seed(LevelFilterIdentifier)?; 196 // Every variant is a unit variant. 197 variant.unit_variant()?; 198 Ok(level_filter) 199 } 200 } 201 202 deserializer.deserialize_enum("LevelFilter", &LOG_LEVEL_NAMES, LevelFilterEnum) 203 } 204 } 205 206 #[cfg(test)] 207 mod tests { 208 extern crate serde_test; 209 use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token}; 210 211 use {Level, LevelFilter}; 212 level_token(variant: &'static str) -> Token213 fn level_token(variant: &'static str) -> Token { 214 Token::UnitVariant { 215 name: "Level", 216 variant: variant, 217 } 218 } 219 level_bytes_tokens(variant: &'static [u8]) -> [Token; 3]220 fn level_bytes_tokens(variant: &'static [u8]) -> [Token; 3] { 221 [ 222 Token::Enum { name: "Level" }, 223 Token::Bytes(variant), 224 Token::Unit, 225 ] 226 } 227 level_variant_tokens(variant: u32) -> [Token; 3]228 fn level_variant_tokens(variant: u32) -> [Token; 3] { 229 [ 230 Token::Enum { name: "Level" }, 231 Token::U32(variant), 232 Token::Unit, 233 ] 234 } 235 level_filter_token(variant: &'static str) -> Token236 fn level_filter_token(variant: &'static str) -> Token { 237 Token::UnitVariant { 238 name: "LevelFilter", 239 variant: variant, 240 } 241 } 242 level_filter_bytes_tokens(variant: &'static [u8]) -> [Token; 3]243 fn level_filter_bytes_tokens(variant: &'static [u8]) -> [Token; 3] { 244 [ 245 Token::Enum { 246 name: "LevelFilter", 247 }, 248 Token::Bytes(variant), 249 Token::Unit, 250 ] 251 } 252 level_filter_variant_tokens(variant: u32) -> [Token; 3]253 fn level_filter_variant_tokens(variant: u32) -> [Token; 3] { 254 [ 255 Token::Enum { 256 name: "LevelFilter", 257 }, 258 Token::U32(variant), 259 Token::Unit, 260 ] 261 } 262 263 #[test] test_level_ser_de()264 fn test_level_ser_de() { 265 let cases = [ 266 (Level::Error, [level_token("ERROR")]), 267 (Level::Warn, [level_token("WARN")]), 268 (Level::Info, [level_token("INFO")]), 269 (Level::Debug, [level_token("DEBUG")]), 270 (Level::Trace, [level_token("TRACE")]), 271 ]; 272 273 for &(s, expected) in &cases { 274 assert_tokens(&s, &expected); 275 } 276 } 277 278 #[test] test_level_case_insensitive()279 fn test_level_case_insensitive() { 280 let cases = [ 281 (Level::Error, [level_token("error")]), 282 (Level::Warn, [level_token("warn")]), 283 (Level::Info, [level_token("info")]), 284 (Level::Debug, [level_token("debug")]), 285 (Level::Trace, [level_token("trace")]), 286 ]; 287 288 for &(s, expected) in &cases { 289 assert_de_tokens(&s, &expected); 290 } 291 } 292 293 #[test] test_level_de_bytes()294 fn test_level_de_bytes() { 295 let cases = [ 296 (Level::Error, level_bytes_tokens(b"ERROR")), 297 (Level::Warn, level_bytes_tokens(b"WARN")), 298 (Level::Info, level_bytes_tokens(b"INFO")), 299 (Level::Debug, level_bytes_tokens(b"DEBUG")), 300 (Level::Trace, level_bytes_tokens(b"TRACE")), 301 ]; 302 303 for &(value, tokens) in &cases { 304 assert_de_tokens(&value, &tokens); 305 } 306 } 307 308 #[test] test_level_de_variant_index()309 fn test_level_de_variant_index() { 310 let cases = [ 311 (Level::Error, level_variant_tokens(0)), 312 (Level::Warn, level_variant_tokens(1)), 313 (Level::Info, level_variant_tokens(2)), 314 (Level::Debug, level_variant_tokens(3)), 315 (Level::Trace, level_variant_tokens(4)), 316 ]; 317 318 for &(value, tokens) in &cases { 319 assert_de_tokens(&value, &tokens); 320 } 321 } 322 323 #[test] test_level_de_error()324 fn test_level_de_error() { 325 let msg = "unknown variant `errorx`, expected one of \ 326 `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`"; 327 assert_de_tokens_error::<Level>(&[level_token("errorx")], msg); 328 } 329 330 #[test] test_level_filter_ser_de()331 fn test_level_filter_ser_de() { 332 let cases = [ 333 (LevelFilter::Off, [level_filter_token("OFF")]), 334 (LevelFilter::Error, [level_filter_token("ERROR")]), 335 (LevelFilter::Warn, [level_filter_token("WARN")]), 336 (LevelFilter::Info, [level_filter_token("INFO")]), 337 (LevelFilter::Debug, [level_filter_token("DEBUG")]), 338 (LevelFilter::Trace, [level_filter_token("TRACE")]), 339 ]; 340 341 for &(s, expected) in &cases { 342 assert_tokens(&s, &expected); 343 } 344 } 345 346 #[test] test_level_filter_case_insensitive()347 fn test_level_filter_case_insensitive() { 348 let cases = [ 349 (LevelFilter::Off, [level_filter_token("off")]), 350 (LevelFilter::Error, [level_filter_token("error")]), 351 (LevelFilter::Warn, [level_filter_token("warn")]), 352 (LevelFilter::Info, [level_filter_token("info")]), 353 (LevelFilter::Debug, [level_filter_token("debug")]), 354 (LevelFilter::Trace, [level_filter_token("trace")]), 355 ]; 356 357 for &(s, expected) in &cases { 358 assert_de_tokens(&s, &expected); 359 } 360 } 361 362 #[test] test_level_filter_de_bytes()363 fn test_level_filter_de_bytes() { 364 let cases = [ 365 (LevelFilter::Off, level_filter_bytes_tokens(b"OFF")), 366 (LevelFilter::Error, level_filter_bytes_tokens(b"ERROR")), 367 (LevelFilter::Warn, level_filter_bytes_tokens(b"WARN")), 368 (LevelFilter::Info, level_filter_bytes_tokens(b"INFO")), 369 (LevelFilter::Debug, level_filter_bytes_tokens(b"DEBUG")), 370 (LevelFilter::Trace, level_filter_bytes_tokens(b"TRACE")), 371 ]; 372 373 for &(value, tokens) in &cases { 374 assert_de_tokens(&value, &tokens); 375 } 376 } 377 378 #[test] test_level_filter_de_variant_index()379 fn test_level_filter_de_variant_index() { 380 let cases = [ 381 (LevelFilter::Off, level_filter_variant_tokens(0)), 382 (LevelFilter::Error, level_filter_variant_tokens(1)), 383 (LevelFilter::Warn, level_filter_variant_tokens(2)), 384 (LevelFilter::Info, level_filter_variant_tokens(3)), 385 (LevelFilter::Debug, level_filter_variant_tokens(4)), 386 (LevelFilter::Trace, level_filter_variant_tokens(5)), 387 ]; 388 389 for &(value, tokens) in &cases { 390 assert_de_tokens(&value, &tokens); 391 } 392 } 393 394 #[test] test_level_filter_de_error()395 fn test_level_filter_de_error() { 396 let msg = "unknown variant `errorx`, expected one of \ 397 `OFF`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`"; 398 assert_de_tokens_error::<LevelFilter>(&[level_filter_token("errorx")], msg); 399 } 400 } 401