Advertisement
Guest User

Untitled

a guest
Jun 18th, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.70 KB | None | 0 0
  1. use serde::{Deserialize, Deserializer};
  2.  
  3. fn from_string<'de, D, T>(deserializer: D) -> Result<T, D::Error>
  4. where
  5. T: Default + std::str::FromStr + Deserialize<'de>,
  6. D: Deserializer<'de>,
  7. <T as std::str::FromStr>::Err: std::fmt::Display,
  8. {
  9. #[derive(Debug, Deserialize)]
  10. #[serde(untagged)]
  11. enum Value<T> {
  12. From(String),
  13. Into(T),
  14. }
  15.  
  16. let result: Result<Value<T>, D::Error> = Deserialize::deserialize(deserializer);
  17. if let Ok(s) = result {
  18. match s {
  19. Value::From(v) => v.parse::<T>().map_err(serde::de::Error::custom),
  20. Value::Into(v) => Ok(v),
  21. }
  22. } else {
  23. Ok(T::default())
  24. }
  25. }
  26.  
  27. fn into_string<'de, D>(deserializer: D) -> Result<String, D::Error>
  28. where
  29. D: Deserializer<'de>,
  30. {
  31. #[derive(Debug, Deserialize)]
  32. #[serde(untagged)]
  33. enum Value {
  34. String(String),
  35. Int(i64),
  36. Uint(u64),
  37. Float(f64),
  38. Bool(bool),
  39. Char(char),
  40. }
  41.  
  42. let result: Result<Value, D::Error> = Deserialize::deserialize(deserializer);
  43. if let Ok(value) = result {
  44. match value {
  45. Value::String(v) => Ok(v),
  46. Value::Int(v) => Ok(v.to_string()),
  47. Value::Uint(v) => Ok(v.to_string()),
  48. Value::Float(v) => Ok(v.to_string()),
  49. Value::Bool(v) => Ok(v.to_string()),
  50. Value::Char(v) => Ok(v.to_string()),
  51. }
  52. } else {
  53. Ok(String::new())
  54. }
  55. }
  56.  
  57. pub fn into_vec<'de, T, D>(deserializer: D) -> Result<Vec<T>, D::Error>
  58. where
  59. T: Deserialize<'de>,
  60. D: Deserializer<'de>,
  61. {
  62. #[derive(Debug, Deserialize)]
  63. #[serde(untagged)]
  64. enum Value<T> {
  65. Into(Vec<T>),
  66. From(T),
  67. }
  68.  
  69. let result: Result<Value<T>, D::Error> = Deserialize::deserialize(deserializer);
  70. if let Ok(value) = result {
  71. match value {
  72. Value::Into(v) => Ok(v),
  73. Value::From(v) => Ok(vec![v]),
  74. }
  75. } else {
  76. Ok(vec![])
  77. }
  78. }
  79.  
  80. fn extract_attr<'de, T, D>(deserializer: D, attr: &str) -> Result<T, D::Error>
  81. where
  82. T: Deserialize<'de> + Default + std::fmt::Debug + Clone,
  83. D: Deserializer<'de>,
  84. {
  85. use std::collections::HashMap;
  86.  
  87. #[derive(Debug, Deserialize)]
  88. #[serde(untagged)]
  89. enum Value<T> {
  90. From(HashMap<String, T>),
  91. Into(T),
  92. }
  93.  
  94. let result: Result<Value<T>, D::Error> = serde::Deserialize::deserialize(deserializer);
  95. if let Ok(value) = result {
  96. match value {
  97. Value::From(map) => {
  98. if let Some(value) = map.get(attr) {
  99. Ok(value.clone())
  100. } else {
  101. Ok(T::default())
  102. }
  103. }
  104. Value::Into(v) => Ok(v),
  105. }
  106. } else {
  107. Ok(T::default())
  108. }
  109. }
  110.  
  111. #[macro_export]
  112. macro_rules! make_extract {
  113. ($name:ident, $attr:expr) => {
  114. pub fn $name<'de, T, D>(deserializer: D) -> Result<T, D::Error>
  115. where
  116. T: serde::Deserialize<'de> + Default + std::fmt::Debug + Clone,
  117. D: serde::Deserializer<'de>,
  118. {
  119. extract_attr(deserializer, $attr)
  120. }
  121. };
  122. }
  123.  
  124. make_extract!(extract_text, "#text");
  125. make_extract!(extract_value, "$value");
  126.  
  127. #[derive(Debug, Deserialize)]
  128. struct Address {
  129. #[serde(deserialize_with = "into_string")]
  130. plz: String,
  131. #[serde(deserialize_with = "extract_value")]
  132. id: u32
  133. }
  134.  
  135. #[derive(Debug, Deserialize)]
  136. struct Person {
  137. #[serde(deserialize_with = "from_string")]
  138. age: u32,
  139. #[serde(deserialize_with = "into_vec")]
  140. address: Vec<Address>
  141. }
  142.  
  143. fn main() {
  144. let json = r#"{ "age": "42", "address": { "plz": 99999, "id": { "$value": 23 } } }"#;
  145. let result: serde_json::Result<Person> = serde_json::from_str(json);
  146. dbg!(result);
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement