Advertisement
Guest User

Untitled

a guest
Jun 18th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.95 KB | None | 0 0
  1. [
  2. {
  3. "Name": "a single unit param",
  4. "Units": "m/s"
  5. },
  6. {
  7. "Name": "a multi unit param",
  8. "Units": {
  9. "Metric": {
  10. "Units": "m/s"
  11. },
  12. "Imperial": {
  13. "Units": "ft/s"
  14. }
  15. }
  16. }
  17. ]
  18.  
  19. use serde::de::{self, MapAccess, Visitor};
  20. use serde::{Deserialize, Deserializer}; // 1.0.91
  21. use std::fmt;
  22.  
  23. #[derive(Debug, Deserialize)]
  24. pub struct SingleUnitParam {
  25. name: String,
  26. units: String,
  27. }
  28.  
  29. #[derive(Debug, Deserialize)]
  30. pub struct UnitInfo {
  31. units: String,
  32. }
  33.  
  34. #[derive(Debug, Deserialize)]
  35. pub struct MultiUnits {
  36. metric: UnitInfo,
  37. imperial: UnitInfo,
  38. }
  39.  
  40. #[derive(Debug, Deserialize)]
  41. #[serde(untagged)]
  42. enum StrOrUnitsObj<'a> {
  43. Str(&'a str),
  44. UnitsObj(MultiUnits),
  45. }
  46.  
  47. #[derive(Debug, Deserialize)]
  48. pub struct MultiUnitParam {
  49. name: String,
  50. units: MultiUnits,
  51. }
  52.  
  53. #[derive(Debug)]
  54. pub enum Param {
  55. Single(SingleUnitParam),
  56. Multiple(MultiUnitParam),
  57. }
  58.  
  59. impl<'de> Deserialize<'de> for Param {
  60. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  61. where
  62. D: Deserializer<'de>,
  63. {
  64. enum Field {
  65. Name,
  66. UnitsAsObj,
  67. UnitsAsStr,
  68. };
  69.  
  70. impl<'de> Deserialize<'de> for Field {
  71. fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
  72. where
  73. D: Deserializer<'de>,
  74. {
  75. struct FieldVisitor;
  76.  
  77. impl<'de> Visitor<'de> for FieldVisitor {
  78. type Value = Field;
  79.  
  80. fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  81. formatter.write_str("`Name` or `Units`")
  82. }
  83.  
  84. fn visit_str<E>(self, value: &str) -> Result<Field, E>
  85. where
  86. E: de::Error,
  87. {
  88. match value {
  89. "Name" => Ok(Field::Name),
  90. "Units" => Ok({
  91. let val = StrOrUnitsObj::deserialize(deserializer).unwrap();
  92.  
  93. match val {
  94. StrOrUnitsObj::Str(s) => Field::UnitsAsObj,
  95. StrOrUnitsObj::UnitsObj(obj) => Field::UnitsAsStr,
  96. }
  97. }),
  98. _ => Err(de::Error::unknown_field(value, FIELDS)),
  99. }
  100. }
  101. }
  102.  
  103. deserializer.deserialize_identifier(FieldVisitor)
  104. }
  105. }
  106.  
  107. struct ParamVisitor;
  108.  
  109. impl<'de> Visitor<'de> for ParamVisitor {
  110. type Value = Param;
  111.  
  112. fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  113. formatter.write_str("enum Param")
  114. }
  115.  
  116. fn visit_map<V>(self, mut map: V) -> Result<Param, V::Error>
  117. where
  118. V: MapAccess<'de>,
  119. {
  120. let mut name = None;
  121. let mut units_as_string = None;
  122. let mut units_as_object = None;
  123. while let Some(key) = map.next_key()? {
  124. match key {
  125. Field::Name => {
  126. if name.is_some() {
  127. return Err(de::Error::duplicate_field("Name"));
  128. }
  129. name = Some(map.next_value()?);
  130. }
  131. Field::UnitsAsObj => {
  132. if units_as_object.is_some() {
  133. return Err(de::Error::duplicate_field("Units"));
  134. }
  135. units_as_object = Some(map.next_value()?);
  136. }
  137. Field::UnitsAsStr => {
  138. if units_as_string.is_some() {
  139. return Err(de::Error::duplicate_field("Units"));
  140. }
  141. units_as_string = Some(map.next_value()?);
  142. }
  143. }
  144. }
  145. let name = name.ok_or_else(|| de::Error::missing_field("Name"))?;
  146. if let Some(units_as_object) = units_as_object {
  147. Ok(Param::Multiple(MultiUnitParam {
  148. name: name,
  149. units: units_as_object,
  150. }))
  151. } else {
  152. let units_as_string =
  153. units_as_string.ok_or_else(|| de::Error::missing_field("Units"))?;
  154. Ok(Param::Single(SingleUnitParam {
  155. name: name,
  156. units: units_as_string,
  157. }))
  158. }
  159. }
  160. }
  161.  
  162. const FIELDS: &'static [&'static str] = &["Name", "Units"];
  163. deserializer.deserialize_struct("Param", FIELDS, ParamVisitor)
  164. }
  165. }
  166.  
  167. fn main() {
  168. let json_raw = r#"[
  169. { "Name": "a single unit param", "Units": "m/s" },
  170. { "Name": "a multi unit param", "Units": { "Metric": { "Units": "m/s" }, "Imperial": { "Units": "ft/s" } } }
  171. ]"#;
  172. let j: Vec<Param> = serde_json::from_str(&json_raw).unwrap();
  173. match &j[0] {
  174. Param::Single(p) => {
  175. assert_eq!(p.name, "a single unit param");
  176. assert_eq!(p.units, "m/s");
  177. }
  178. Param::Multiple(_p) => panic!("Expected SingleUnitParam, actual MultiUnitParam"),
  179. }
  180. match &j[1] {
  181. Param::Single(_p) => panic!("Expected MultiUnitParam, actual SingleUnitParam"),
  182. Param::Multiple(p) => {
  183. assert_eq!(p.name, "a multi unit param");
  184. assert_eq!(p.units.metric.units, "m/s");
  185. assert_eq!(p.units.imperial.units, "ft/s");
  186. }
  187. }
  188. }
  189.  
  190. fn visit_str<E>(self, value: &str) -> Result<Field, E>
  191. where
  192. E: de::Error,
  193. {
  194. match value {
  195. "Name" => Ok(Field::Name),
  196. "Units" => Ok({
  197. let val = StrOrUnitsObj::deserialize(deserializer).unwrap();
  198.  
  199. match val {
  200. StrOrUnitsObj::Str(s) => {
  201. Field::UnitsAsObj
  202. },
  203. StrOrUnitsObj::UnitsObj(obj) => {
  204. Field::UnitsAsStr
  205. }
  206. }
  207. }),
  208. _ => Err(de::Error::unknown_field(value, FIELDS)),
  209. }
  210. }
  211.  
  212. use std::fmt;
  213. use serde::{Deserialize, Deserializer}; // 1.0.91
  214. use serde::de::{self, Visitor, MapAccess};
  215.  
  216. #[derive(Debug, Deserialize)]
  217. pub struct SingleUnitParam {
  218. name: String,
  219. units: String,
  220. }
  221.  
  222. #[derive(Debug, Deserialize)]
  223. pub struct UnitInfo {
  224. #[serde(alias = "Units")]
  225. units: String,
  226. }
  227.  
  228. #[derive(Debug, Deserialize)]
  229. pub struct MultiUnits {
  230. #[serde(alias = "Metric")]
  231. metric: UnitInfo,
  232. #[serde(alias = "Imperial")]
  233. imperial: UnitInfo,
  234. }
  235.  
  236. #[derive(Debug, Deserialize)]
  237. #[serde(untagged)]
  238. enum StrOrUnitsObj<'a> {
  239. Str(&'a str),
  240. UnitsObj(MultiUnits)
  241. }
  242.  
  243. #[derive(Debug, Deserialize)]
  244. pub struct MultiUnitParam {
  245. name: String,
  246. units: MultiUnits,
  247. }
  248.  
  249. #[derive(Debug)]
  250. pub enum Param {
  251. Single(SingleUnitParam),
  252. Multiple(MultiUnitParam),
  253. }
  254.  
  255. impl<'de> Deserialize<'de> for Param {
  256. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  257. where
  258. D: Deserializer<'de>,
  259. {
  260. enum Field { Name, Units/*, UnitsAsObj, UnitsAsStr*/ };
  261.  
  262. impl<'de> Deserialize<'de> for Field {
  263. fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
  264. where
  265. D: Deserializer<'de>,
  266. {
  267. struct FieldVisitor;
  268.  
  269. impl<'de> Visitor<'de> for FieldVisitor {
  270. type Value = Field;
  271.  
  272. fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  273. formatter.write_str("`Name` or `Units`")
  274. }
  275.  
  276. fn visit_str<E>(self, value: &str) -> Result<Field, E>
  277. where
  278. E: de::Error,
  279. {
  280. match value {
  281. "Name" => Ok(Field::Name),
  282. "Units" => Ok(Field::Units),
  283. // Can't get access to the JSON value to inspect it here.
  284. // "Units" => Ok({
  285. // let val = StrOrUnitsObj::deserialize(deserializer).unwrap();
  286.  
  287. // match val {
  288. // StrOrUnitsObj::Str(s) => {
  289. // Field::UnitsAsObj
  290. // },
  291. // StrOrUnitsObj::UnitsObj(obj) => {
  292. // Field::UnitsAsStr
  293. // }
  294. // }
  295. // }),
  296. _ => Err(de::Error::unknown_field(value, FIELDS)),
  297. }
  298. }
  299. }
  300.  
  301. deserializer.deserialize_identifier(FieldVisitor)
  302. }
  303. }
  304.  
  305. struct ParamVisitor;
  306.  
  307. impl<'de> Visitor<'de> for ParamVisitor {
  308. type Value = Param;
  309.  
  310. fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  311. formatter.write_str("enum Param")
  312. }
  313.  
  314. fn visit_map<V>(self, mut map: V) -> Result<Param, V::Error>
  315. where
  316. V: MapAccess<'de>,
  317. {
  318. let mut name = None;
  319. let mut units_as_string = None;
  320. let mut units_as_object = None;
  321. while let Some(key) = map.next_key()? {
  322. match key {
  323. Field::Name => {
  324. if name.is_some() {
  325. return Err(de::Error::duplicate_field("Name"));
  326. }
  327. name = Some(map.next_value()?);
  328. }
  329. Field::Units => {
  330. if units_as_string.is_some() || units_as_object.is_some() {
  331. return Err(de::Error::duplicate_field("Units"));
  332. }
  333. // Here is where we can get the JSON value and check its type.
  334. let v: serde_json::Value = map.next_value()?;
  335. if v.is_object() {
  336. let v: MultiUnits = serde_json::from_value(v).unwrap();
  337. units_as_object = Some(v);
  338. } else if v.is_string() {
  339. units_as_string = Some(v.as_str().unwrap().to_owned());
  340. }
  341. }
  342. // Field::UnitsAsObj => {
  343. // if units_as_object.is_some() {
  344. // return Err(de::Error::duplicate_field("Units"));
  345. // }
  346. // units_as_object = Some(map.next_value()?);
  347. // }
  348. // Field::UnitsAsStr => {
  349. // if units_as_string.is_some() {
  350. // return Err(de::Error::duplicate_field("Units"));
  351. // }
  352. // units_as_string = Some(map.next_value()?);
  353. // }
  354. }
  355. }
  356. let name = name.ok_or_else(|| de::Error::missing_field("Name"))?;
  357. if let Some(units_as_object) = units_as_object {
  358. Ok(Param::Multiple(MultiUnitParam {
  359. name: name,
  360. units: units_as_object
  361. }))
  362. } else {
  363. let units_as_string = units_as_string.ok_or_else(|| de::Error::missing_field("Units"))?;
  364. Ok(Param::Single(SingleUnitParam {
  365. name: name,
  366. units: units_as_string
  367. }))
  368. }
  369. }
  370. }
  371.  
  372. const FIELDS: &'static [&'static str] = &["Name", "Units"];
  373. deserializer.deserialize_struct("Param", FIELDS, ParamVisitor)
  374. }
  375. }
  376.  
  377. fn main() {
  378. let json_raw = r#"[
  379. { "Name": "a single unit param", "Units": "m/s" },
  380. { "Name": "a multi unit param", "Units": { "Metric": { "Units": "m/s" }, "Imperial": { "Units": "ft/s" } } }
  381. ]"#;
  382. let j: Vec<Param> = serde_json::from_str(&json_raw).unwrap();
  383. match &j[0] {
  384. Param::Single(p) => {
  385. assert_eq!(p.name, "a single unit param");
  386. assert_eq!(p.units, "m/s");
  387. },
  388. Param::Multiple(_p) => panic!("Expected SingleUnitParam, actual MultiUnitParam")
  389. }
  390. match &j[1] {
  391. Param::Single(_p) => panic!("Expected MultiUnitParam, actual SingleUnitParam"),
  392. Param::Multiple(p) => {
  393. assert_eq!(p.name, "a multi unit param");
  394. assert_eq!(p.units.metric.units, "m/s");
  395. assert_eq!(p.units.imperial.units, "ft/s");
  396. }
  397. }
  398. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement