proxygen
folly::json_patch Class Reference

#include <json_patch.h>

Classes

struct  parse_error
 
struct  patch_operation
 

Public Types

enum  parse_error_code : uint8_t {
  parse_error_code::undefined, parse_error_code::invalid_shape, parse_error_code::missing_op, parse_error_code::unknown_op,
  parse_error_code::malformed_op, parse_error_code::missing_path_attr, parse_error_code::malformed_path_attr, parse_error_code::missing_from_attr,
  parse_error_code::malformed_from_attr, parse_error_code::missing_value_attr, parse_error_code::overlapping_pointers
}
 
enum  patch_operation_code : uint8_t {
  patch_operation_code::invalid = 0, patch_operation_code::test, patch_operation_code::remove, patch_operation_code::add,
  patch_operation_code::replace, patch_operation_code::move, patch_operation_code::copy
}
 

Public Member Functions

 json_patch ()=default
 
 ~json_patch ()=default
 
std::vector< patch_operation > const & ops () const
 

Static Public Member Functions

static folly::Expected< json_patch, parse_errortry_parse (dynamic const &obj) noexcept
 

Private Attributes

std::vector< patch_operationops_
 

Detailed Description

Definition at line 34 of file json_patch.h.

Member Enumeration Documentation

Enumerator
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 

Definition at line 36 of file json_patch.h.

36  : uint8_t {
37  undefined,
38  invalid_shape,
39  missing_op,
40  unknown_op,
41  malformed_op,
42  missing_path_attr,
43  malformed_path_attr,
44  missing_from_attr,
45  malformed_from_attr,
46  missing_value_attr,
47  overlapping_pointers,
48  };
Enumerator
invalid 
test 
remove 
add 
replace 
move 
copy 

Definition at line 61 of file json_patch.h.

61  : uint8_t {
62  invalid = 0,
63  test,
64  remove,
65  add,
66  replace,
67  move,
68  copy,
69  };
auto add
Definition: BaseTest.cpp:70
static uint64_t test(std::string name, bool fc_, bool dedicated_, bool tc_, bool syncops_, uint64_t base)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void BENCHFUN() replace(size_t iters, size_t arg)
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72

Constructor & Destructor Documentation

folly::json_patch::json_patch ( )
default
folly::json_patch::~json_patch ( )
default

Member Function Documentation

std::vector< json_patch::patch_operation > const & folly::json_patch::ops ( ) const

Definition at line 151 of file json_patch.cpp.

References ops_.

151  {
152  return ops_;
153 }
std::vector< patch_operation > ops_
Definition: json_patch.h:101
Expected< json_patch, json_patch::parse_error > folly::json_patch::try_parse ( dynamic const &  obj)
staticnoexcept

Definition at line 38 of file json_patch.cpp.

References add, copy, folly::json_patch::patch_operation::from, invalid, invalid_shape, folly::makeUnexpected(), malformed_from_attr, malformed_op, malformed_path_attr, missing_from_attr, missing_op, missing_path_attr, missing_value_attr, move, folly::gen::move, folly::json_patch::patch_operation::op_code, ops_, overlapping_pointers, folly::json_patch::patch_operation::path, remove, replace, test, folly::json_pointer::try_parse(), unknown_op, and folly::json_patch::patch_operation::value.

39  {
40  using err_code = parse_error_code;
41 
42  json_patch patch;
43  if (!obj.isArray()) {
44  return makeUnexpected(parse_error{err_code::invalid_shape, &obj});
45  }
46  for (auto const& elem : obj) {
47  if (!elem.isObject()) {
48  return makeUnexpected(parse_error{err_code::invalid_shape, &elem});
49  }
50  auto const* op_ptr = elem.get_ptr(kOpTag);
51  if (!op_ptr) {
52  return makeUnexpected(parse_error{err_code::missing_op, &elem});
53  }
54  if (!op_ptr->isString()) {
55  return makeUnexpected(parse_error{err_code::malformed_op, &elem});
56  }
57  auto const op_str = op_ptr->asString();
58  patch_operation op;
59 
60  // extract 'from' attribute
61  {
62  auto const* from_ptr = elem.get_ptr(kFromTag);
63  if (from_ptr) {
64  if (!from_ptr->isString()) {
65  return makeUnexpected(parse_error{err_code::invalid_shape, &elem});
66  }
67  auto json_ptr = json_pointer::try_parse(from_ptr->asString());
68  if (!json_ptr.hasValue()) {
69  return makeUnexpected(
70  parse_error{err_code::malformed_from_attr, &elem});
71  }
72  op.from = json_ptr.value();
73  }
74  }
75 
76  // extract 'path' attribute
77  {
78  auto const* path_ptr = elem.get_ptr(kPathTag);
79  if (!path_ptr) {
80  return makeUnexpected(parse_error{err_code::missing_path_attr, &elem});
81  }
82  if (!path_ptr->isString()) {
83  return makeUnexpected(
84  parse_error{err_code::malformed_path_attr, &elem});
85  }
86  auto const json_ptr = json_pointer::try_parse(path_ptr->asString());
87  if (!json_ptr.hasValue()) {
88  return makeUnexpected(
89  parse_error{err_code::malformed_path_attr, &elem});
90  }
91  op.path = json_ptr.value();
92  }
93 
94  // extract 'value' attribute
95  {
96  auto const* val_ptr = elem.get_ptr(kValueTag);
97  if (val_ptr) {
98  op.value = *val_ptr;
99  }
100  }
101 
102  // check mandatory attributes - different per operation
103  // NOTE: per RFC, the surplus attributes (e.g. 'from' with 'add')
104  // should be simply ignored
105 
107 
108  if (op_str == kOperationTest) {
109  if (!op.value) {
110  return makeUnexpected(parse_error{err_code::missing_value_attr, &elem});
111  }
112  op.op_code = op_code::test;
113  } else if (op_str == kOperationRemove) {
114  op.op_code = op_code::remove;
115  } else if (op_str == kOperationAdd) {
116  if (!op.value) {
117  return makeUnexpected(parse_error{err_code::missing_value_attr, &elem});
118  }
119  op.op_code = op_code::add;
120  } else if (op_str == kOperationReplace) {
121  if (!op.value) {
122  return makeUnexpected(parse_error{err_code::missing_value_attr, &elem});
123  }
124  op.op_code = op_code::replace;
125  } else if (op_str == kOperationMove) {
126  if (!op.from) {
127  return makeUnexpected(parse_error{err_code::missing_from_attr, &elem});
128  }
129  // is from a proper prefix to path?
130  if (op.from->is_prefix_of(op.path)) {
131  return makeUnexpected(
132  parse_error{err_code::overlapping_pointers, &elem});
133  }
134  op.op_code = op_code::move;
135  } else if (op_str == kOperationCopy) {
136  if (!op.from) {
137  return makeUnexpected(parse_error{err_code::missing_from_attr, &elem});
138  }
139  op.op_code = op_code::copy;
140  }
141 
142  if (op.op_code != op_code::invalid) {
143  patch.ops_.emplace_back(std::move(op));
144  } else {
145  return makeUnexpected(parse_error{err_code::unknown_op, &elem});
146  }
147  }
148  return patch;
149 }
static Expected< json_pointer, parse_error > try_parse(StringPiece const str)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
json_patch()=default
constexpr Unexpected< typename std::decay< Error >::type > makeUnexpected(Error &&)
Definition: Expected.h:785

Member Data Documentation

std::vector<patch_operation> folly::json_patch::ops_
private

Definition at line 101 of file json_patch.h.

Referenced by ops(), and try_parse().


The documentation for this class was generated from the following files: