Advertisement
Guest User

Untitled

a guest
Sep 20th, 2019
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.34 KB | None | 0 0
  1. use std::collections::HashMap;
  2.  
  3. #[derive(Debug, PartialEq)]
  4. enum Json {
  5. Number(i64),
  6. Bool(bool),
  7. String(String),
  8. Array(Vec<Json>),
  9. Object(HashMap<String, Json>),
  10. }
  11.  
  12. struct Pointer<'a, 'b> {
  13. value: &'a mut Json,
  14. path: Vec<&'b str>,
  15. position: usize,
  16. }
  17.  
  18. enum Either<'a, 'b> {
  19. Left(Pointer<'a, 'b>),
  20. Right(Vec<&'b str>)
  21. }
  22.  
  23. fn nearest_mut<'a, 'b>(obj: &'a mut Json, path: Vec<&'b str>) -> Pointer<'a, 'b> {
  24. let valid_path = nearest_path(obj, path);
  25. exact_mut(obj, valid_path).unwrap()
  26. }
  27. fn exact_mut<'a, 'b>(obj: &'a mut Json, path: Vec<&'b str>) -> Option<Pointer<'a, 'b>> {
  28. let mut i = 0;
  29. let mut target = obj;
  30. for token in path.iter() {
  31. i += 1;
  32. // borrow checker gets confused about `target` being mutably borrowed too many times because of the loop
  33. // this once-per-loop binding makes the scope clearer and circumvents the error
  34. let target_once = target;
  35. let target_opt = match *target_once {
  36. Json::Object(ref mut map) => map.get_mut(*token),
  37. Json::Array(ref mut list) => match token.parse::<usize>() {
  38. Ok(t) => list.get_mut(t),
  39. Err(_) => None,
  40. },
  41. _ => None,
  42. };
  43. if let Some(t) = target_opt {
  44. target = t;
  45. } else {
  46. return None;
  47. }
  48. }
  49. Some(Pointer {
  50. path,
  51. position: i,
  52. value: target,
  53. })
  54. }
  55. /// Return a mutable pointer to JSON element having shared
  56. /// the nearest common path with provided JSON.
  57. fn nearest_path<'a, 'b>(obj: &'a Json, path: Vec<&'b str>) -> Vec<&'b str> {
  58. let mut i = 0;
  59. let mut target = obj;
  60. let mut valid_paths = vec![];
  61. for token in path.iter() {
  62. // borrow checker gets confused about `target` being mutably borrowed too many times because of the loop
  63. // this once-per-loop binding makes the scope clearer and circumvents the error
  64. let target_opt = match *target {
  65. Json::Object(ref map) => map.get(*token),
  66. Json::Array(ref list) => match token.parse::<usize>() {
  67. Ok(t) => list.get(t),
  68. Err(_) => None,
  69. },
  70. _ => None,
  71. };
  72. if let Some(t) = target_opt {
  73. target = t;
  74. valid_paths.push(*token)
  75. } else {
  76. return valid_paths;
  77. }
  78. }
  79. return valid_paths
  80. }
  81.  
  82. #[test]
  83. fn nearest_path_test() {
  84. let baz_obj = Json::String("baz".to_string());
  85. let bar_obj = Json::Object(vec![
  86. ("baz".to_string(), baz_obj)].into_iter().collect());
  87. let mut foo_obj = Json::Object(vec![
  88. ("bar".to_string(), bar_obj)].into_iter().collect());
  89. let output:Vec<String> = match nearest_mut(&mut foo_obj, vec!["foo","baz"]).value {
  90. Json::Object(k) => k.keys().map(|r| r.clone()).collect(),
  91. _ => vec![]
  92. };
  93. assert_eq!(output, vec!["bar".to_string()])
  94. }
  95.  
  96. #[test]
  97. fn exact_path_test() {
  98. let baz_obj = Json::String("baz".to_string());
  99. let bar_obj = Json::Object(vec![
  100. ("baz".to_string(), baz_obj)].into_iter().collect());
  101. let mut foo_obj = Json::Object(vec![
  102. ("bar".to_string(), bar_obj)].into_iter().collect());
  103. let output:String = match nearest_mut(&mut foo_obj, vec!["bar","baz"]).value {
  104. Json::String(r) => r.clone(),
  105. _ => "".to_string()
  106. };
  107. assert_eq!(output, "baz".to_string())
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement