json_patch.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * Copyright 2011-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. #include <folly/Expected.h>
  18. #include <folly/Optional.h>
  19. #include <folly/dynamic.h>
  20. #include <folly/json_pointer.h>
  21. namespace folly {
  22. /*
  23. * json_patch
  24. *
  25. * As described in RFC 6902 "JSON Patch".
  26. *
  27. * Implements parsing. Application over data structures must be
  28. * implemented separately.
  29. */
  30. class json_patch {
  31. public:
  32. enum class parse_error_code : uint8_t {
  33. undefined,
  34. invalid_shape,
  35. missing_op,
  36. unknown_op,
  37. malformed_op,
  38. missing_path_attr,
  39. malformed_path_attr,
  40. missing_from_attr,
  41. malformed_from_attr,
  42. missing_value_attr,
  43. overlapping_pointers,
  44. };
  45. /*
  46. * If parsing JSON patch object fails we return err code along with
  47. * pointer to part of JSON document that we could not parse
  48. */
  49. struct parse_error {
  50. // one of the above error codes
  51. parse_error_code error_code{parse_error_code::undefined};
  52. // pointer to object that caused the error
  53. dynamic const* obj{};
  54. };
  55. enum class patch_operation_code : uint8_t {
  56. invalid = 0,
  57. test,
  58. remove,
  59. add,
  60. replace,
  61. move,
  62. copy,
  63. };
  64. /*
  65. * Single JSON patch operation. Argument may vary based on op type
  66. */
  67. struct patch_operation {
  68. patch_operation_code op_code{patch_operation_code::invalid};
  69. json_pointer path;
  70. Optional<json_pointer> from;
  71. Optional<dynamic> value;
  72. friend bool operator==(
  73. patch_operation const& lhs,
  74. patch_operation const& rhs) {
  75. return lhs.op_code == rhs.op_code && lhs.path == rhs.path &&
  76. lhs.from == rhs.from && lhs.value == rhs.value;
  77. }
  78. friend bool operator!=(
  79. patch_operation const& lhs,
  80. patch_operation const& rhs) {
  81. return !(lhs == rhs);
  82. }
  83. };
  84. json_patch() = default;
  85. ~json_patch() = default;
  86. static folly::Expected<json_patch, parse_error> try_parse(
  87. dynamic const& obj) noexcept;
  88. std::vector<patch_operation> const& ops() const;
  89. private:
  90. std::vector<patch_operation> ops_;
  91. };
  92. } // namespace folly