/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include namespace folly { /* * json_patch * * As described in RFC 6902 "JSON Patch". * * Implements parsing. Application over data structures must be * implemented separately. */ class json_patch { public: enum class parse_error_code : uint8_t { undefined, invalid_shape, missing_op, unknown_op, malformed_op, missing_path_attr, malformed_path_attr, missing_from_attr, malformed_from_attr, missing_value_attr, overlapping_pointers, }; /* * If parsing JSON patch object fails we return err code along with * pointer to part of JSON document that we could not parse */ struct parse_error { // one of the above error codes parse_error_code error_code{parse_error_code::undefined}; // pointer to object that caused the error dynamic const* obj{}; }; enum class patch_operation_code : uint8_t { invalid = 0, test, remove, add, replace, move, copy, }; /* * Single JSON patch operation. Argument may vary based on op type */ struct patch_operation { patch_operation_code op_code{patch_operation_code::invalid}; json_pointer path; Optional from; Optional value; friend bool operator==( patch_operation const& lhs, patch_operation const& rhs) { return lhs.op_code == rhs.op_code && lhs.path == rhs.path && lhs.from == rhs.from && lhs.value == rhs.value; } friend bool operator!=( patch_operation const& lhs, patch_operation const& rhs) { return !(lhs == rhs); } }; json_patch() = default; ~json_patch() = default; static folly::Expected try_parse( dynamic const& obj) noexcept; std::vector const& ops() const; enum class patch_application_error_code : uint8_t { other, // "from" pointer did not resolve from_not_found, // "path" pointer did not resolve path_not_found, // "test" condition failed test_failed, }; struct patch_application_error { patch_application_error_code error_code{}; // index of the patch element (in array) that caused error size_t index{}; }; /* * Mutate supplied object in accordance with patch operations. Leaves * object in partially modified state if one of the operations fails. */ Expected apply(folly::dynamic& obj); private: std::vector ops_; }; } // namespace folly