forked from facebook/fbthrift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
debug.h
158 lines (142 loc) · 4.39 KB
/
debug.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
* Copyright (c) Meta Platforms, Inc. and 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.
*/
#ifndef THRIFT_FATAL_DEBUG_H_
#define THRIFT_FATAL_DEBUG_H_ 1
#include <string>
#include <folly/Range.h>
/**
* READ ME FIRST: this header enhances Thrift with debugging utilities.
*
* Please refer to the top of `thrift/lib/cpp2/reflection/reflection.h` on how
* to enable compile-time reflection for Thrift types. The present header relies
* on it for its functionality.
*
* TROUBLESHOOTING:
* - make sure you've followed the instructions on `reflection.h` to enable
* generation of compile-time reflection;
* - make sure you've included the metadata for your Thrift types, as specified
* in `reflection.h`.
*
* @author: Marcelo Juchem <[email protected]>
*/
#include <thrift/lib/cpp2/reflection/internal/debug-inl-pre.h>
#include <thrift/lib/cpp2/reflection/pretty_print.h>
namespace apache {
namespace thrift {
/**
* Compares two objects for equality, field-by-fields, in a DFS traversal.
* Returns a boolean that tells whether they're equal or not.
*
* Once a mismatch has been found, the callback is called as if with the
* following signature:
*
* void operator ()(
* T const* lhs,
* T const* rhs,
* folly::StringPiece path,
* folly::StringPiece message
* ) const;
*
* lhs: the left-hand side mismatched field or nullptr if the field is not
* present in the lhs object
* rhs: the right-hand side mismatched field or nullptr if the field is not
* present in the rhs object
* path: the path in the DFS where the mismatch happened
* message: a message explaining the mismatch
*
* @author: Marcelo Juchem <[email protected]>
*/
template <typename TC, typename T, typename Callback>
bool debug_equals(
T const& lhs, T const& rhs, Callback&& callback, std::string path = "$") {
return apache::thrift::detail::debug_equals<TC>(path, lhs, rhs, callback);
}
template <typename T, typename Callback>
bool debug_equals(
T const& lhs, T const& rhs, Callback&& callback, std::string path = "$") {
using TC = type_class_of_thrift_class_enum_t<T>;
return apache::thrift::detail::debug_equals<TC>(path, lhs, rhs, callback);
}
/**
* A handy callback for `debug_equals()` that outputs to a given stream.
*
* See `make_debug_output_callback` for a convenient way to create an instance
* of this callback.
*
* @author: Marcelo Juchem <[email protected]>
*/
template <typename Output>
struct debug_output_callback {
explicit debug_output_callback(
Output& out, folly::StringPiece lhs, folly::StringPiece rhs)
: out_(out), lhs_(lhs), rhs_(rhs) {}
template <typename TC, typename T>
void operator()(
TC,
T const* lhs,
T const* rhs,
folly::StringPiece path,
folly::StringPiece message) const {
out_ << path << ": " << message;
if (lhs) {
out_ << "\n"
<< " " << lhs_ << ":\n";
pretty_print<TC>(out_, *lhs, " ", " ");
}
if (rhs) {
out_ << "\n"
<< " " << rhs_ << ":\n";
pretty_print<TC>(out_, *rhs, " ", " ");
}
out_ << "\n";
}
private:
Output& out_;
folly::StringPiece lhs_;
folly::StringPiece rhs_;
};
/**
* A convenient way to create an instance of `debug_output_callback`.
*
* Example:
*
* bool const equals = debug_equals(
* lhs,
* rhs,
* make_debug_output_callback(std::cout)
* );
*
* EXPECT_TRUE(
* debug_equals(
* lhs,
* rhs,
* make_debug_output_callback(LOG(ERROR))
* )
* );
*
* @author: Marcelo Juchem <[email protected]>
*/
template <typename Output>
debug_output_callback<Output> make_debug_output_callback(
Output& output,
folly::StringPiece lhs = "lhs",
folly::StringPiece rhs = "rhs") {
return debug_output_callback<Output>(output, lhs, rhs);
}
} // namespace thrift
} // namespace apache
#include <thrift/lib/cpp2/reflection/internal/debug-inl-post.h>
#endif // THRIFT_FATAL_DEBUG_H_