Advertisement
Guest User

Untitled

a guest
Feb 20th, 2019
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.93 KB | None | 0 0
  1. use void::Void;
  2.  
  3. extern crate serde;
  4.  
  5. use serde::{Deserialize, Serialize};
  6. use serde::de::Deserializer;
  7.  
  8. use std::marker::PhantomData;
  9. use std::str::FromStr;
  10. use std::fmt;
  11. use serde::de::Visitor;
  12. use serde::de;
  13.  
  14. #[derive(Serialize, Deserialize)]
  15. struct Wow {
  16. #[serde(deserialize_with = "bool_or_string")]
  17. hello: String,
  18. }
  19.  
  20. fn bool_or_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
  21. where
  22. T: Deserialize<'de> + FromStr<Err = Void>,
  23. D: Deserializer<'de>,
  24. {
  25. // This is a Visitor that forwards string types to T's `FromStr` impl and
  26. // forwards map types to T's `Deserialize` impl. The `PhantomData` is to
  27. // keep the compiler from complaining about T being an unused generic type
  28. // parameter. We need T in order to know the Value type for the Visitor
  29. // impl.
  30. struct BoolOrString<T>(PhantomData<fn() -> T>);
  31.  
  32. impl<'de, T> Visitor<'de> for BoolOrString<T>
  33. where
  34. T: Deserialize<'de> + FromStr<Err = Void>,
  35. {
  36. type Value = T;
  37.  
  38. fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  39. formatter.write_str("bool or string")
  40. }
  41.  
  42. fn visit_bool<E>(self, value: &str) -> Result<&str, E>
  43. where
  44. E: de::Error,
  45. {
  46. Ok(if value {"true"} else {"false"})
  47. }
  48.  
  49. fn visit_str<E>(self, value: &str) -> Result<T, E>
  50. where
  51. E: de::Error,
  52. {
  53. Ok(FromStr::from_str(value).unwrap())
  54. }
  55. }
  56.  
  57. deserializer.deserialize_any(BoolOrString(PhantomData))
  58. }
  59.  
  60. #[cfg(test)]
  61. mod tests {
  62. use super::*;
  63.  
  64. #[test]
  65. fn test_parsing() {
  66. let data0 = r#"{
  67. "hello": "yeah"
  68. ]
  69. }"#;
  70.  
  71. let data1 = r#"{
  72. "hello": false
  73. ]
  74. }"#;
  75.  
  76. let wow0: Wow = serde_json::from_str(data0).unwrap();
  77. let wow1: Wow = serde_json::from_str(data1).unwrap();
  78. }
  79. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement