Fancy printer predicate now takes current JSON object
The API is ugly at the moment. Will fix with an ugly implementation soon.
This commit is contained in:
parent
c7a64b8846
commit
edb6b25569
@ -43,19 +43,31 @@ struct fancy_serializer_style
|
|||||||
|
|
||||||
bool multiline = false;
|
bool multiline = false;
|
||||||
|
|
||||||
void set_old_multiline()
|
fancy_serializer_style() = default;
|
||||||
{
|
|
||||||
space_after_colon = space_after_comma = multiline = true;
|
fancy_serializer_style(bool s_colon, bool s_comma, bool ml)
|
||||||
}
|
: space_after_colon(s_colon), space_after_comma(s_comma), multiline(ml)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static const fancy_serializer_style preset_compact;
|
||||||
|
static const fancy_serializer_style preset_one_line;
|
||||||
|
static const fancy_serializer_style preset_multiline;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fancy_serializer_style fancy_serializer_style::preset_compact(false, false, false);
|
||||||
|
const fancy_serializer_style fancy_serializer_style::preset_one_line(true, true, false);
|
||||||
|
const fancy_serializer_style fancy_serializer_style::preset_multiline(true, true, true);
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
class basic_fancy_serializer_stylizer
|
class basic_fancy_serializer_stylizer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using json_pointer_t = json_pointer<BasicJsonType>;
|
using json_pointer_t = json_pointer<BasicJsonType>;
|
||||||
using matcher_predicate = std::function<bool (const json_pointer_t&)>;
|
|
||||||
|
using json_matcher_predicate = std::function<bool (const BasicJsonType&)>;
|
||||||
|
using context_matcher_predicate = std::function<bool (const json_pointer_t&)>;
|
||||||
|
using matcher_predicate = std::function<bool (const json_pointer_t&, const BasicJsonType&)>;
|
||||||
|
|
||||||
basic_fancy_serializer_stylizer(fancy_serializer_style const& ds)
|
basic_fancy_serializer_stylizer(fancy_serializer_style const& ds)
|
||||||
: default_style(ds)
|
: default_style(ds)
|
||||||
@ -76,11 +88,12 @@ class basic_fancy_serializer_stylizer
|
|||||||
|
|
||||||
const fancy_serializer_style* get_new_style_or_active(
|
const fancy_serializer_style* get_new_style_or_active(
|
||||||
const json_pointer_t& pointer,
|
const json_pointer_t& pointer,
|
||||||
|
const json& j,
|
||||||
const fancy_serializer_style* active_style) const
|
const fancy_serializer_style* active_style) const
|
||||||
{
|
{
|
||||||
for (auto const& pair : styles)
|
for (auto const& pair : styles)
|
||||||
{
|
{
|
||||||
if (pair.first(pointer))
|
if (pair.first(pointer, j))
|
||||||
{
|
{
|
||||||
return &pair.second;
|
return &pair.second;
|
||||||
}
|
}
|
||||||
@ -96,15 +109,40 @@ class basic_fancy_serializer_stylizer
|
|||||||
return styles.back().second;
|
return styles.back().second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fancy_serializer_style& register_style(
|
||||||
|
json_matcher_predicate p,
|
||||||
|
fancy_serializer_style style = fancy_serializer_style())
|
||||||
|
{
|
||||||
|
auto wrapper = [p](const json_pointer_t&, const BasicJsonType & j)
|
||||||
|
{
|
||||||
|
return p(j);
|
||||||
|
};
|
||||||
|
styles.emplace_back(wrapper, style);
|
||||||
|
return styles.back().second;
|
||||||
|
}
|
||||||
|
|
||||||
|
fancy_serializer_style& register_style(
|
||||||
|
context_matcher_predicate p,
|
||||||
|
fancy_serializer_style style = fancy_serializer_style())
|
||||||
|
{
|
||||||
|
auto wrapper = [p](const json_pointer_t& c, const BasicJsonType&)
|
||||||
|
{
|
||||||
|
return p(c);
|
||||||
|
};
|
||||||
|
styles.emplace_back(wrapper, style);
|
||||||
|
return styles.back().second;
|
||||||
|
}
|
||||||
|
|
||||||
fancy_serializer_style& register_key_matcher_style(
|
fancy_serializer_style& register_key_matcher_style(
|
||||||
string_t str,
|
string_t str,
|
||||||
fancy_serializer_style style = fancy_serializer_style())
|
fancy_serializer_style style = fancy_serializer_style())
|
||||||
{
|
{
|
||||||
return register_style([str](const json_pointer_t& pointer)
|
using pred = context_matcher_predicate;
|
||||||
|
return register_style(pred([str](const json_pointer_t& pointer)
|
||||||
{
|
{
|
||||||
return (pointer.cbegin() != pointer.cend())
|
return (pointer.cbegin() != pointer.cend())
|
||||||
&& (*pointer.crbegin() == str);
|
&& (*pointer.crbegin() == str);
|
||||||
},
|
}),
|
||||||
style);
|
style);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +218,7 @@ class fancy_serializer
|
|||||||
const fancy_serializer_style* active_style,
|
const fancy_serializer_style* active_style,
|
||||||
const json_pointer_t& context)
|
const json_pointer_t& context)
|
||||||
{
|
{
|
||||||
active_style = stylizer.get_new_style_or_active(context, active_style);
|
active_style = stylizer.get_new_style_or_active(context, val, active_style);
|
||||||
|
|
||||||
switch (val.m_type)
|
switch (val.m_type)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10848,19 +10848,31 @@ struct fancy_serializer_style
|
|||||||
|
|
||||||
bool multiline = false;
|
bool multiline = false;
|
||||||
|
|
||||||
void set_old_multiline()
|
fancy_serializer_style() = default;
|
||||||
{
|
|
||||||
space_after_colon = space_after_comma = multiline = true;
|
fancy_serializer_style(bool s_colon, bool s_comma, bool ml)
|
||||||
}
|
: space_after_colon(s_colon), space_after_comma(s_comma), multiline(ml)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static const fancy_serializer_style preset_compact;
|
||||||
|
static const fancy_serializer_style preset_one_line;
|
||||||
|
static const fancy_serializer_style preset_multiline;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fancy_serializer_style fancy_serializer_style::preset_compact(false, false, false);
|
||||||
|
const fancy_serializer_style fancy_serializer_style::preset_one_line(true, true, false);
|
||||||
|
const fancy_serializer_style fancy_serializer_style::preset_multiline(true, true, true);
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
class basic_fancy_serializer_stylizer
|
class basic_fancy_serializer_stylizer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using json_pointer_t = json_pointer<BasicJsonType>;
|
using json_pointer_t = json_pointer<BasicJsonType>;
|
||||||
using matcher_predicate = std::function<bool (const json_pointer_t&)>;
|
|
||||||
|
using json_matcher_predicate = std::function<bool (const BasicJsonType&)>;
|
||||||
|
using context_matcher_predicate = std::function<bool (const json_pointer_t&)>;
|
||||||
|
using matcher_predicate = std::function<bool (const json_pointer_t&, const BasicJsonType&)>;
|
||||||
|
|
||||||
basic_fancy_serializer_stylizer(fancy_serializer_style const& ds)
|
basic_fancy_serializer_stylizer(fancy_serializer_style const& ds)
|
||||||
: default_style(ds)
|
: default_style(ds)
|
||||||
@ -10881,11 +10893,12 @@ class basic_fancy_serializer_stylizer
|
|||||||
|
|
||||||
const fancy_serializer_style* get_new_style_or_active(
|
const fancy_serializer_style* get_new_style_or_active(
|
||||||
const json_pointer_t& pointer,
|
const json_pointer_t& pointer,
|
||||||
|
const json& j,
|
||||||
const fancy_serializer_style* active_style) const
|
const fancy_serializer_style* active_style) const
|
||||||
{
|
{
|
||||||
for (auto const& pair : styles)
|
for (auto const& pair : styles)
|
||||||
{
|
{
|
||||||
if (pair.first(pointer))
|
if (pair.first(pointer, j))
|
||||||
{
|
{
|
||||||
return &pair.second;
|
return &pair.second;
|
||||||
}
|
}
|
||||||
@ -10901,15 +10914,40 @@ class basic_fancy_serializer_stylizer
|
|||||||
return styles.back().second;
|
return styles.back().second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fancy_serializer_style& register_style(
|
||||||
|
json_matcher_predicate p,
|
||||||
|
fancy_serializer_style style = fancy_serializer_style())
|
||||||
|
{
|
||||||
|
auto wrapper = [p](const json_pointer_t&, const BasicJsonType & j)
|
||||||
|
{
|
||||||
|
return p(j);
|
||||||
|
};
|
||||||
|
styles.emplace_back(wrapper, style);
|
||||||
|
return styles.back().second;
|
||||||
|
}
|
||||||
|
|
||||||
|
fancy_serializer_style& register_style(
|
||||||
|
context_matcher_predicate p,
|
||||||
|
fancy_serializer_style style = fancy_serializer_style())
|
||||||
|
{
|
||||||
|
auto wrapper = [p](const json_pointer_t& c, const BasicJsonType&)
|
||||||
|
{
|
||||||
|
return p(c);
|
||||||
|
};
|
||||||
|
styles.emplace_back(wrapper, style);
|
||||||
|
return styles.back().second;
|
||||||
|
}
|
||||||
|
|
||||||
fancy_serializer_style& register_key_matcher_style(
|
fancy_serializer_style& register_key_matcher_style(
|
||||||
string_t str,
|
string_t str,
|
||||||
fancy_serializer_style style = fancy_serializer_style())
|
fancy_serializer_style style = fancy_serializer_style())
|
||||||
{
|
{
|
||||||
return register_style([str](const json_pointer_t& pointer)
|
using pred = context_matcher_predicate;
|
||||||
|
return register_style(pred([str](const json_pointer_t& pointer)
|
||||||
{
|
{
|
||||||
return (pointer.cbegin() != pointer.cend())
|
return (pointer.cbegin() != pointer.cend())
|
||||||
&& (*pointer.crbegin() == str);
|
&& (*pointer.crbegin() == str);
|
||||||
},
|
}),
|
||||||
style);
|
style);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10985,7 +11023,7 @@ class fancy_serializer
|
|||||||
const fancy_serializer_style* active_style,
|
const fancy_serializer_style* active_style,
|
||||||
const json_pointer_t& context)
|
const json_pointer_t& context)
|
||||||
{
|
{
|
||||||
active_style = stylizer.get_new_style_or_active(context, active_style);
|
active_style = stylizer.get_new_style_or_active(context, val, active_style);
|
||||||
|
|
||||||
switch (val.m_type)
|
switch (val.m_type)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -203,7 +203,8 @@ TEST_CASE("serialization")
|
|||||||
auto str_flat = fancy_to_string({1, {1}}, style);
|
auto str_flat = fancy_to_string({1, {1}}, style);
|
||||||
CHECK(str_flat == "[1,[...]]");
|
CHECK(str_flat == "[1,[...]]");
|
||||||
|
|
||||||
style.set_old_multiline();
|
style = fancy_serializer_style::preset_multiline;
|
||||||
|
style.depth_limit = 1;
|
||||||
auto str_lines = fancy_to_string({1, {1}}, style);
|
auto str_lines = fancy_to_string({1, {1}}, style);
|
||||||
CHECK(str_lines == dedent(R"(
|
CHECK(str_lines == dedent(R"(
|
||||||
[
|
[
|
||||||
@ -220,7 +221,8 @@ TEST_CASE("serialization")
|
|||||||
auto str_flat = fancy_to_string({1, {{"one", 1}}}, style);
|
auto str_flat = fancy_to_string({1, {{"one", 1}}}, style);
|
||||||
CHECK(str_flat == "[1,{...}]");
|
CHECK(str_flat == "[1,{...}]");
|
||||||
|
|
||||||
style.set_old_multiline();
|
style = fancy_serializer_style::preset_multiline;
|
||||||
|
style.depth_limit = 1;
|
||||||
auto str_lines = fancy_to_string({1, {{"one", 1}}}, style);
|
auto str_lines = fancy_to_string({1, {{"one", 1}}}, style);
|
||||||
CHECK(str_lines == dedent(R"(
|
CHECK(str_lines == dedent(R"(
|
||||||
[
|
[
|
||||||
@ -235,8 +237,8 @@ TEST_CASE("serialization")
|
|||||||
SECTION("can style objects of a key differently")
|
SECTION("can style objects of a key differently")
|
||||||
{
|
{
|
||||||
fancy_serializer_stylizer stylizer;
|
fancy_serializer_stylizer stylizer;
|
||||||
stylizer.get_default_style().set_old_multiline();
|
stylizer.get_default_style() = fancy_serializer_style::preset_multiline;
|
||||||
stylizer.register_key_matcher_style("one line").multiline = false;
|
stylizer.register_key_matcher_style("one line");
|
||||||
|
|
||||||
auto str = fancy_to_string(
|
auto str = fancy_to_string(
|
||||||
{
|
{
|
||||||
@ -262,8 +264,8 @@ TEST_CASE("serialization")
|
|||||||
SECTION("changes propagate (unless overridden)")
|
SECTION("changes propagate (unless overridden)")
|
||||||
{
|
{
|
||||||
fancy_serializer_stylizer stylizer;
|
fancy_serializer_stylizer stylizer;
|
||||||
stylizer.get_default_style().set_old_multiline();
|
stylizer.get_default_style() = fancy_serializer_style::preset_multiline;
|
||||||
stylizer.register_key_matcher_style("one line").indent_step = 0;
|
stylizer.register_key_matcher_style("one line");
|
||||||
|
|
||||||
auto str = fancy_to_string(
|
auto str = fancy_to_string(
|
||||||
{
|
{
|
||||||
@ -279,18 +281,20 @@ TEST_CASE("serialization")
|
|||||||
})"));
|
})"));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("example of more sophisticated matcher")
|
SECTION("example of more sophisticated context matcher")
|
||||||
{
|
{
|
||||||
|
using pred = fancy_serializer_stylizer::context_matcher_predicate;
|
||||||
|
|
||||||
fancy_serializer_stylizer stylizer;
|
fancy_serializer_stylizer stylizer;
|
||||||
stylizer.get_default_style().set_old_multiline();
|
stylizer.get_default_style() = fancy_serializer_style::preset_multiline;
|
||||||
|
|
||||||
stylizer.register_style(
|
stylizer.register_style(
|
||||||
[] (const json_pointer<json>& context)
|
pred([] (const json_pointer<json>& context)
|
||||||
{
|
{
|
||||||
// Matches if context[-2] is "each elem on one line"
|
// Matches if context[-2] is "each elem on one line"
|
||||||
return (context.cend() - context.cbegin() >= 2)
|
return (context.cend() - context.cbegin() >= 2)
|
||||||
&& (*(context.cend() - 2) == "each elem on one line");
|
&& (*(context.cend() - 2) == "each elem on one line");
|
||||||
}
|
})
|
||||||
).space_after_comma = true;
|
).space_after_comma = true;
|
||||||
|
|
||||||
auto str = fancy_to_string(
|
auto str = fancy_to_string(
|
||||||
@ -324,6 +328,40 @@ TEST_CASE("serialization")
|
|||||||
]
|
]
|
||||||
})"));
|
})"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("example of more sophisticated json matcher")
|
||||||
|
{
|
||||||
|
using pred = fancy_serializer_stylizer::json_matcher_predicate;
|
||||||
|
|
||||||
|
fancy_serializer_stylizer stylizer;
|
||||||
|
stylizer.get_default_style() = fancy_serializer_style::preset_multiline;
|
||||||
|
|
||||||
|
stylizer.register_style(
|
||||||
|
pred([] (const json & j)
|
||||||
|
{
|
||||||
|
return j.type() == json::value_t::array;
|
||||||
|
})
|
||||||
|
) = fancy_serializer_style::preset_one_line;
|
||||||
|
|
||||||
|
auto str = fancy_to_string(
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"an array", {1, 2, 3}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"an object", {{"key", "val"}}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
stylizer);
|
||||||
|
|
||||||
|
CHECK(str == dedent(R"(
|
||||||
|
{
|
||||||
|
"an array": [1, 2, 3],
|
||||||
|
"an object": {
|
||||||
|
"key": "val"
|
||||||
|
}
|
||||||
|
})"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Spaces after commas are controllable separately from multiline")
|
SECTION("Spaces after commas are controllable separately from multiline")
|
||||||
@ -346,8 +384,7 @@ TEST_CASE("serialization")
|
|||||||
|
|
||||||
SECTION("multiline can have no space")
|
SECTION("multiline can have no space")
|
||||||
{
|
{
|
||||||
fancy_serializer_style style;
|
fancy_serializer_style style = fancy_serializer_style::preset_multiline;
|
||||||
style.set_old_multiline();
|
|
||||||
style.space_after_colon = false;
|
style.space_after_colon = false;
|
||||||
auto str = fancy_to_string({{"one", 1}}, style);
|
auto str = fancy_to_string({{"one", 1}}, style);
|
||||||
CHECK(str == dedent(R"(
|
CHECK(str == dedent(R"(
|
||||||
@ -360,8 +397,7 @@ TEST_CASE("serialization")
|
|||||||
|
|
||||||
SECTION("given width")
|
SECTION("given width")
|
||||||
{
|
{
|
||||||
fancy_serializer_style style;
|
fancy_serializer_style style = fancy_serializer_style::preset_multiline;
|
||||||
style.set_old_multiline();
|
|
||||||
auto str = fancy_to_string({"foo", 1, 2, 3, false, {{"one", 1}}}, style);
|
auto str = fancy_to_string({"foo", 1, 2, 3, false, {{"one", 1}}}, style);
|
||||||
CHECK(str == dedent(R"(
|
CHECK(str == dedent(R"(
|
||||||
[
|
[
|
||||||
@ -378,10 +414,9 @@ TEST_CASE("serialization")
|
|||||||
|
|
||||||
SECTION("given fill")
|
SECTION("given fill")
|
||||||
{
|
{
|
||||||
fancy_serializer_style style;
|
fancy_serializer_style style = fancy_serializer_style::preset_multiline;
|
||||||
style.indent_step = 1;
|
style.indent_step = 1;
|
||||||
style.indent_char = '\t';
|
style.indent_char = '\t';
|
||||||
style.set_old_multiline();
|
|
||||||
|
|
||||||
auto str = fancy_to_string({"foo", 1, 2, 3, false, {{"one", 1}}}, style);
|
auto str = fancy_to_string({"foo", 1, 2, 3, false, {{"one", 1}}}, style);
|
||||||
CHECK(str ==
|
CHECK(str ==
|
||||||
@ -400,10 +435,9 @@ TEST_CASE("serialization")
|
|||||||
|
|
||||||
SECTION("indent_char is honored for deep indents in lists")
|
SECTION("indent_char is honored for deep indents in lists")
|
||||||
{
|
{
|
||||||
fancy_serializer_style style;
|
fancy_serializer_style style = fancy_serializer_style::preset_multiline;
|
||||||
style.indent_step = 300;
|
style.indent_step = 300;
|
||||||
style.indent_char = 'X';
|
style.indent_char = 'X';
|
||||||
style.set_old_multiline();
|
|
||||||
|
|
||||||
auto str = fancy_to_string({1, {1}}, style);
|
auto str = fancy_to_string({1, {1}}, style);
|
||||||
|
|
||||||
@ -419,10 +453,9 @@ TEST_CASE("serialization")
|
|||||||
|
|
||||||
SECTION("indent_char is honored for deep indents in objects")
|
SECTION("indent_char is honored for deep indents in objects")
|
||||||
{
|
{
|
||||||
fancy_serializer_style style;
|
fancy_serializer_style style = fancy_serializer_style::preset_multiline;
|
||||||
style.indent_step = 300;
|
style.indent_step = 300;
|
||||||
style.indent_char = 'X';
|
style.indent_char = 'X';
|
||||||
style.set_old_multiline();
|
|
||||||
|
|
||||||
auto str = fancy_to_string({{"key", {{"key", 1}}}}, style);
|
auto str = fancy_to_string({{"key", {{"key", 1}}}}, style);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user