Skip to content

Commit 0f89389

Browse files
Alfred Fullerfacebook-github-bot
authored andcommitted
Add clear support to BoolPatch
Summary: Which will unset an optional value, or clear a non-optional valuie. Differential Revision: D39161781 fbshipit-source-id: 140a6c23443b88577390a9586f50b0d38b936f7c
1 parent d69b8dd commit 0f89389

File tree

5 files changed

+60
-10
lines changed

5 files changed

+60
-10
lines changed

third-party/thrift/src/thrift/lib/cpp2/op/detail/BasePatch.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,13 @@ class BaseAssignPatch : public BasePatch<Patch, Derived> {
200200
using Base::resetAnd;
201201
~BaseAssignPatch() = default; // abstract base class
202202

203+
FOLLY_NODISCARD bool hasAssign() const { return hasValue(data_.assign()); }
203204
FOLLY_NODISCARD value_type& assignOr(value_type& value) noexcept {
204-
return hasValue(data_.assign()) ? *data_.assign() : value;
205+
return hasAssign() ? *data_.assign() : value;
205206
}
206207

207208
bool applyAssign(value_type& val) const {
208-
if (hasValue(data_.assign())) {
209+
if (hasAssign()) {
209210
val = *data_.assign();
210211
return true;
211212
}
@@ -218,7 +219,7 @@ class BaseAssignPatch : public BasePatch<Patch, Derived> {
218219
data_ = std::forward<U>(next).toThrift();
219220
return true;
220221
}
221-
if (hasValue(data_.assign())) {
222+
if (hasAssign()) {
222223
next.apply(*data_.assign());
223224
return true;
224225
}
@@ -239,15 +240,29 @@ class BaseClearPatch : public BaseAssignPatch<Patch, Derived> {
239240
public:
240241
using Base::Base;
241242
using Base::operator=;
243+
using Base::apply;
242244

243245
FOLLY_NODISCARD static Derived createClear() {
244246
Derived patch;
245247
patch.clear();
246248
return patch;
247249
}
248250

251+
// Clear resets optional fields.
252+
template <typename U>
253+
if_opt_type<folly::remove_cvref_t<U>> apply(U&& field) const {
254+
if (data_.clear() == true && !hasAssign()) {
255+
field.reset();
256+
} else if (field.has_value()) {
257+
derived().apply(*std::forward<U>(field));
258+
}
259+
}
260+
249261
protected:
262+
using Base::applyAssign;
250263
using Base::data_;
264+
using Base::derived;
265+
using Base::hasAssign;
251266
using Base::mergeAssign;
252267
using Base::resetAnd;
253268
~BaseClearPatch() = default;
@@ -266,6 +281,17 @@ class BaseClearPatch : public BaseAssignPatch<Patch, Derived> {
266281
return mergeAssign(std::forward<U>(next));
267282
}
268283

284+
template <typename Tag>
285+
bool applyAssignAndClear(T& val) const {
286+
if (applyAssign(val)) {
287+
return true;
288+
}
289+
if (data_.clear() == true) {
290+
op::clear<Tag>(val);
291+
}
292+
return false;
293+
}
294+
269295
void clear() { resetAnd().clear() = true; }
270296
FOLLY_NODISCARD T& clearAnd() { return (clear(), data_); }
271297
};

third-party/thrift/src/thrift/lib/cpp2/op/detail/ValuePatch.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@ class AssignPatch : public BaseAssignPatch<Patch, AssignPatch<Patch>> {
5353

5454
// Patch must have the following fields:
5555
// optional T assign;
56+
// bool clear;
5657
// bool invert;
5758
template <typename Patch>
58-
class BoolPatch : public BaseAssignPatch<Patch, BoolPatch<Patch>> {
59-
using Base = BaseAssignPatch<Patch, BoolPatch>;
59+
class BoolPatch : public BaseClearPatch<Patch, BoolPatch<Patch>> {
60+
using Base = BaseClearPatch<Patch, BoolPatch>;
6061
using T = typename Base::value_type;
6162

6263
public:
@@ -72,23 +73,23 @@ class BoolPatch : public BaseAssignPatch<Patch, BoolPatch<Patch>> {
7273
}
7374

7475
void apply(T& val) const {
75-
if (!applyAssign(val) && *data_.invert()) {
76+
if (!Base::template applyAssignAndClear<type::bool_t>(val) &&
77+
*data_.invert()) {
7678
val = !val;
7779
}
7880
}
7981

8082
template <typename U>
8183
void merge(U&& next) {
82-
if (!mergeAssign(std::forward<U>(next))) {
84+
if (!mergeAssignAndClear(std::forward<U>(next))) {
8385
*data_.invert() ^= *next.toThrift().invert();
8486
}
8587
}
8688

8789
private:
88-
using Base::applyAssign;
8990
using Base::assignOr;
9091
using Base::data_;
91-
using Base::mergeAssign;
92+
using Base::mergeAssignAndClear;
9293

9394
friend BoolPatch operator!(BoolPatch val) { return (val.invert(), val); }
9495
};

third-party/thrift/src/thrift/lib/cpp2/protocol/Patch.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,17 @@ void ApplyPatch::operator()(const Object& patch, protocol::Value& value) const {
155155
}
156156

157157
void ApplyPatch::operator()(const Object& patch, bool& value) const {
158-
checkOps(patch, Value::Type::boolValue, {PatchOp::Assign, PatchOp::Put});
158+
checkOps(
159+
patch,
160+
Value::Type::boolValue,
161+
{PatchOp::Assign, PatchOp::Put, PatchOp::Clear});
159162
if (applyAssign<type::bool_t>(patch, value)) {
160163
return; // Ignore all other ops.
161164
}
165+
if (auto* clear = findOp(patch, PatchOp::Clear);
166+
clear != nullptr && *clear->boolValue_ref()) {
167+
value = false;
168+
}
162169
if (auto* invert = findOp(patch, PatchOp::Put)) { // Put is Invert for bool.
163170
if (argAs<type::bool_t>(*invert)) {
164171
value = !value;

third-party/thrift/src/thrift/lib/thrift/patch.thrift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ struct BoolPatch {
5858
*/
5959
1: optional bool assign;
6060

61+
/** Clear any set value. */
62+
2: bool clear;
63+
6164
/** If the bool value should be inverted. */
6265
9: bool invert;
6366
}

third-party/thrift/src/thrift/test/StructPatchTest.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <thrift/lib/cpp2/op/Testing.h>
2222
#include <thrift/lib/cpp2/op/detail/StructPatch.h>
2323
#include <thrift/lib/cpp2/type/Testing.h>
24+
#include <thrift/lib/thrift/gen-cpp2/patch_types.h>
2425
#include <thrift/test/gen-cpp2/StructPatchTest_fatal_types.h>
2526
#include <thrift/test/gen-cpp2/StructPatchTest_types.h>
2627

@@ -115,6 +116,18 @@ TEST(StructPatchTest, Clear) {
115116
test::expectPatch(op::StringPatch::createClear(), {"hi"}, "");
116117
}
117118

119+
TEST(StructPatchTest, ClearField_Bool) {
120+
MyStruct actual;
121+
122+
actual.boolVal() = true;
123+
op::BoolPatch::createClear().apply(actual.boolVal());
124+
EXPECT_FALSE(*actual.boolVal());
125+
126+
actual.optBoolVal() = true;
127+
op::BoolPatch::createClear().apply(actual.optBoolVal());
128+
EXPECT_FALSE(actual.optBoolVal().has_value());
129+
}
130+
118131
TEST(StructPatchTest, Patch) {
119132
MyStruct val;
120133
val.stringVal() = "hi";

0 commit comments

Comments
 (0)