Advertisement
Guest User

Untitled

a guest
Jun 26th, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.43 KB | None | 0 0
  1. use std::fmt;
  2. use serde::{Deserialize, Deserializer}; // 1.0.91
  3. use serde::de::{self, Visitor, MapAccess};
  4.  
  5. #[derive(Debug, Deserialize)]
  6. pub struct SingleUnitParam {
  7. name: String,
  8. units: String,
  9. }
  10.  
  11. #[derive(Debug, Deserialize)]
  12. pub struct UnitInfo {
  13. units: String,
  14. }
  15.  
  16. #[derive(Debug, Deserialize)]
  17. pub struct MultiUnits {
  18. metric: UnitInfo,
  19. imperial: UnitInfo,
  20. }
  21.  
  22. #[derive(Debug, Deserialize)]
  23. #[serde(untagged)]
  24. enum StrOrUnitsObj<'a> {
  25. Str(&'a str),
  26. UnitsObj(MultiUnits)
  27. }
  28.  
  29. #[derive(Debug, Deserialize)]
  30. pub struct MultiUnitParam {
  31. name: String,
  32. units: MultiUnits,
  33. }
  34.  
  35. #[derive(Debug)]
  36. pub enum Param {
  37. Single(SingleUnitParam),
  38. Multiple(MultiUnitParam),
  39. }
  40.  
  41. impl<'de> Deserialize<'de> for Param {
  42. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  43. where
  44. D: Deserializer<'de>,
  45. {
  46. enum Field { Name, UnitsAsObj, UnitsAsStr };
  47.  
  48. impl<'de> Deserialize<'de> for Field {
  49. fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
  50. where
  51. D: Deserializer<'de>,
  52. {
  53. struct FieldVisitor;
  54.  
  55. impl<'de> Visitor<'de> for FieldVisitor {
  56. type Value = Field;
  57.  
  58. fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  59. formatter.write_str("`Name` or `Units`")
  60. }
  61.  
  62. fn visit_str<E>(self, value: &str) -> Result<Field, E>
  63. where
  64. E: de::Error,
  65. {
  66. match value {
  67. "Name" => Ok(Field::Name),
  68. "Units" => Ok({
  69. let val = StrOrUnitsObj::deserialize(deserializer).unwrap();
  70.  
  71. match val {
  72. StrOrUnitsObj::Str(s) => {
  73. Field::UnitsAsObj
  74. },
  75. StrOrUnitsObj::UnitsObj(obj) => {
  76. Field::UnitsAsStr
  77. }
  78. }
  79. }),
  80. _ => Err(de::Error::unknown_field(value, FIELDS)),
  81. }
  82. }
  83. }
  84.  
  85. deserializer.deserialize_identifier(FieldVisitor)
  86. }
  87. }
  88.  
  89. struct ParamVisitor;
  90.  
  91. impl<'de> Visitor<'de> for ParamVisitor {
  92. type Value = Param;
  93.  
  94. fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  95. formatter.write_str("enum Param")
  96. }
  97.  
  98. fn visit_map<V>(self, mut map: V) -> Result<Param, V::Error>
  99. where
  100. V: MapAccess<'de>,
  101. {
  102. let mut name = None;
  103. let mut units_as_string = None;
  104. let mut units_as_object = None;
  105. while let Some(key) = map.next_key()? {
  106. match key {
  107. Field::Name => {
  108. if name.is_some() {
  109. return Err(de::Error::duplicate_field("Name"));
  110. }
  111. name = Some(map.next_value()?);
  112. }
  113. Field::UnitsAsObj => {
  114. if units_as_object.is_some() {
  115. return Err(de::Error::duplicate_field("Units"));
  116. }
  117. units_as_object = Some(map.next_value()?);
  118. }
  119. Field::UnitsAsStr => {
  120. if units_as_string.is_some() {
  121. return Err(de::Error::duplicate_field("Units"));
  122. }
  123. units_as_string = Some(map.next_value()?);
  124. }
  125. }
  126. }
  127. let name = name.ok_or_else(|| de::Error::missing_field("Name"))?;
  128. if let Some(units_as_object) = units_as_object {
  129. Ok(Param::Multiple(MultiUnitParam {
  130. name: name,
  131. units: units_as_object
  132. }))
  133. } else {
  134. let units_as_string = units_as_string.ok_or_else(|| de::Error::missing_field("Units"))?;
  135. Ok(Param::Single(SingleUnitParam {
  136. name: name,
  137. units: units_as_string
  138. }))
  139. }
  140. }
  141. }
  142.  
  143. const FIELDS: &'static [&'static str] = &["Name", "Units"];
  144. deserializer.deserialize_struct("Param", FIELDS, ParamVisitor)
  145. }
  146. }
  147.  
  148. fn main() {
  149. let json_raw = r#"[
  150. { "Name": "a single unit param", "Units": "m/s" },
  151. { "Name": "a multi unit param", "Units": { "Metric": { "Units": "m/s" }, "Imperial": { "Units": "ft/s" } } }
  152. ]"#;
  153. let j: Vec<Param> = serde_json::from_str(&json_raw).unwrap();
  154. match &j[0] {
  155. Param::Single(p) => {
  156. assert_eq!(p.name, "a single unit param");
  157. assert_eq!(p.units, "m/s");
  158. },
  159. Param::Multiple(_p) => panic!("Expected SingleUnitParam, actual MultiUnitParam")
  160. }
  161. match &j[1] {
  162. Param::Single(_p) => panic!("Expected MultiUnitParam, actual SingleUnitParam"),
  163. Param::Multiple(p) => {
  164. assert_eq!(p.name, "a multi unit param");
  165. assert_eq!(p.units.metric.units, "m/s");
  166. assert_eq!(p.units.imperial.units, "ft/s");
  167. }
  168. }
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement