Skip to content

Commit 2451595

Browse files
Add skip function for glz::meta to ignore members during write (#1846)
* Add skip function in the meta to ignore elements during write * cleanup * Update json_reflection_test.cpp --------- Co-authored-by: Stephen Berry <stephenberry.developer@gmail.com>
1 parent 58ec7f3 commit 2451595

File tree

5 files changed

+93
-2
lines changed

5 files changed

+93
-2
lines changed

include/glaze/core/reflect.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,11 @@ namespace glz
219219
inline constexpr bool maybe_skipped = [] {
220220
if constexpr (reflect<T>::size > 0) {
221221
constexpr auto N = reflect<T>::size;
222-
if constexpr (Opts.skip_null_members) {
222+
if constexpr (meta_has_skip<T>) {
223+
// If the glz::meta provides a skip method, we assume the user wants to skip fields
224+
return true;
225+
}
226+
else if constexpr (Opts.skip_null_members) {
223227
// if any type could be null then we might skip
224228
return []<size_t... I>(std::index_sequence<I...>) {
225229
return ((always_skipped<field_t<T, I>> || null_t<field_t<T, I>>) || ...);

include/glaze/json/write.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1812,6 +1812,10 @@ namespace glz
18121812
for_each<N>([&]<size_t I>() {
18131813
using val_t = field_t<T, I>;
18141814

1815+
if constexpr (meta_has_skip<T>) {
1816+
if constexpr (meta<T>::skip(reflect<T>::keys[I])) return;
1817+
}
1818+
18151819
if constexpr (always_skipped<val_t>) {
18161820
return;
18171821
}
@@ -1855,7 +1859,7 @@ namespace glz
18551859
first = false;
18561860
}
18571861
else {
1858-
// Null members may be skipped so we cant just write it out for all but the last member
1862+
// Null members may be skipped so we can't just write it out for all but the last member
18591863
if constexpr (Opts.prettify) {
18601864
std::memcpy(&b[ix], ",\n", 2);
18611865
ix += 2;

include/glaze/reflection/get_name.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ namespace glz
123123
template <class T>
124124
struct meta;
125125

126+
// Concept when skip is specified for the type
127+
template <class T>
128+
concept meta_has_skip = requires(T t, const std::string_view s) {
129+
{ glz::meta<std::remove_cvref_t<T>>::skip(s) } -> std::same_as<bool>;
130+
};
131+
126132
// Concept for when rename_key returns exactly std::string (allocates)
127133
template <class T>
128134
concept meta_has_rename_key_string = requires(T t, const std::string_view s) {

tests/json_reflection_test/json_reflection_test.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,21 @@ static_assert(glz::reflectable<my_struct>);
1919

2020
static_assert(glz::name_v<my_struct> == "my_struct");
2121

22+
static_assert(glz::meta_has_skip<my_struct> == false);
23+
24+
struct test_skip
25+
{
26+
};
27+
28+
template <>
29+
struct glz::meta<test_skip>
30+
{
31+
static constexpr bool skip(const std::string_view) { return true; }
32+
};
33+
34+
35+
static_assert(glz::meta_has_skip<test_skip>);
36+
2237
suite reflection = [] {
2338
"reflect_write"_test = [] {
2439
std::string buffer = R"({"i":287,"d":3.14,"hello":"Hello World","arr":[1,2,3]})";

tests/json_test/json_test.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9104,6 +9104,68 @@ suite skip_tests = [] {
91049104
};
91059105
};
91069106

9107+
struct specify_only_skip_obj
9108+
{
9109+
int i{1};
9110+
int j{2};
9111+
int k{3};
9112+
};
9113+
9114+
template <>
9115+
struct glz::meta<specify_only_skip_obj>
9116+
{
9117+
static constexpr bool skip(const std::string_view key) { return key == "j"; }
9118+
};
9119+
9120+
suite specify_only_skip_obj_tests = [] {
9121+
"skip_only_one"_test = [] {
9122+
specify_only_skip_obj obj{};
9123+
expect(glz::write_json(obj) == R"({"i":1,"k":3})") << glz::write_json(obj).value();
9124+
};
9125+
};
9126+
9127+
struct skip_hidden_elements
9128+
{
9129+
int i{1};
9130+
int hidden_j{2};
9131+
int hidden_k{3};
9132+
int l{4};
9133+
};
9134+
9135+
template <>
9136+
struct glz::meta<skip_hidden_elements>
9137+
{
9138+
static constexpr bool skip(const std::string_view key) { return key.starts_with(std::string_view{"hidden"}); }
9139+
};
9140+
9141+
suite skip_hidden_elements_tests = [] {
9142+
"skip_hidden_elements"_test = [] {
9143+
skip_hidden_elements obj{};
9144+
expect(glz::write_json(obj) == R"({"i":1,"l":4})") << glz::write_json(obj).value();
9145+
};
9146+
};
9147+
9148+
struct skip_first_and_last
9149+
{
9150+
int i{1};
9151+
int hidden_j{2};
9152+
int hidden_k{3};
9153+
int l{4};
9154+
};
9155+
9156+
template <>
9157+
struct glz::meta<skip_first_and_last>
9158+
{
9159+
static constexpr bool skip(const std::string_view key) { return key == "i" || key == "l"; }
9160+
};
9161+
9162+
suite skip_first_and_last_tests = [] {
9163+
"skip_first_and_last_tests"_test = [] {
9164+
skip_first_and_last obj{};
9165+
expect(glz::write_json(obj) == R"({"hidden_j":2,"hidden_k":3})") << glz::write_json(obj).value();
9166+
};
9167+
};
9168+
91079169
template <size_t N>
91089170
struct FixedName
91099171
{

0 commit comments

Comments
 (0)