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;
|
||||
|
||||
void set_old_multiline()
|
||||
{
|
||||
space_after_colon = space_after_comma = multiline = true;
|
||||
}
|
||||
fancy_serializer_style() = default;
|
||||
|
||||
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>
|
||||
class basic_fancy_serializer_stylizer
|
||||
{
|
||||
public:
|
||||
using string_t = typename BasicJsonType::string_t;
|
||||
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)
|
||||
: default_style(ds)
|
||||
@ -76,11 +88,12 @@ class basic_fancy_serializer_stylizer
|
||||
|
||||
const fancy_serializer_style* get_new_style_or_active(
|
||||
const json_pointer_t& pointer,
|
||||
const json& j,
|
||||
const fancy_serializer_style* active_style) const
|
||||
{
|
||||
for (auto const& pair : styles)
|
||||
{
|
||||
if (pair.first(pointer))
|
||||
if (pair.first(pointer, j))
|
||||
{
|
||||
return &pair.second;
|
||||
}
|
||||
@ -96,15 +109,40 @@ class basic_fancy_serializer_stylizer
|
||||
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(
|
||||
string_t str,
|
||||
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())
|
||||
&& (*pointer.crbegin() == str);
|
||||
},
|
||||
}),
|
||||
style);
|
||||
}
|
||||
|
||||
@ -180,7 +218,7 @@ class fancy_serializer
|
||||
const fancy_serializer_style* active_style,
|
||||
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)
|
||||
{
|
||||
|
||||
@ -10848,19 +10848,31 @@ struct fancy_serializer_style
|
||||
|
||||
bool multiline = false;
|
||||
|
||||
void set_old_multiline()
|
||||
{
|
||||
space_after_colon = space_after_comma = multiline = true;
|
||||
}
|
||||
fancy_serializer_style() = default;
|
||||
|
||||
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>
|
||||
class basic_fancy_serializer_stylizer
|
||||
{
|
||||
public:
|
||||
using string_t = typename BasicJsonType::string_t;
|
||||
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)
|
||||
: default_style(ds)
|
||||
@ -10881,11 +10893,12 @@ class basic_fancy_serializer_stylizer
|
||||
|
||||
const fancy_serializer_style* get_new_style_or_active(
|
||||
const json_pointer_t& pointer,
|
||||
const json& j,
|
||||
const fancy_serializer_style* active_style) const
|
||||
{
|
||||
for (auto const& pair : styles)
|
||||
{
|
||||
if (pair.first(pointer))
|
||||
if (pair.first(pointer, j))
|
||||
{
|
||||
return &pair.second;
|
||||
}
|
||||
@ -10901,15 +10914,40 @@ class basic_fancy_serializer_stylizer
|
||||
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(
|
||||
string_t str,
|
||||
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())
|
||||
&& (*pointer.crbegin() == str);
|
||||
},
|
||||
}),
|
||||
style);
|
||||
}
|
||||
|
||||
@ -10985,7 +11023,7 @@ class fancy_serializer
|
||||
const fancy_serializer_style* active_style,
|
||||
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)
|
||||
{
|
||||
|
||||
@ -203,7 +203,8 @@ TEST_CASE("serialization")
|
||||
auto str_flat = fancy_to_string({1, {1}}, style);
|
||||
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);
|
||||
CHECK(str_lines == dedent(R"(
|
||||
[
|
||||
@ -220,7 +221,8 @@ TEST_CASE("serialization")
|
||||
auto str_flat = fancy_to_string({1, {{"one", 1}}}, style);
|
||||
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);
|
||||
CHECK(str_lines == dedent(R"(
|
||||
[
|
||||
@ -235,8 +237,8 @@ TEST_CASE("serialization")
|
||||
SECTION("can style objects of a key differently")
|
||||
{
|
||||
fancy_serializer_stylizer stylizer;
|
||||
stylizer.get_default_style().set_old_multiline();
|
||||
stylizer.register_key_matcher_style("one line").multiline = false;
|
||||
stylizer.get_default_style() = fancy_serializer_style::preset_multiline;
|
||||
stylizer.register_key_matcher_style("one line");
|
||||
|
||||
auto str = fancy_to_string(
|
||||
{
|
||||
@ -262,8 +264,8 @@ TEST_CASE("serialization")
|
||||
SECTION("changes propagate (unless overridden)")
|
||||
{
|
||||
fancy_serializer_stylizer stylizer;
|
||||
stylizer.get_default_style().set_old_multiline();
|
||||
stylizer.register_key_matcher_style("one line").indent_step = 0;
|
||||
stylizer.get_default_style() = fancy_serializer_style::preset_multiline;
|
||||
stylizer.register_key_matcher_style("one line");
|
||||
|
||||
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;
|
||||
stylizer.get_default_style().set_old_multiline();
|
||||
stylizer.get_default_style() = fancy_serializer_style::preset_multiline;
|
||||
|
||||
stylizer.register_style(
|
||||
[] (const json_pointer<json>& context)
|
||||
pred([] (const json_pointer<json>& context)
|
||||
{
|
||||
// Matches if context[-2] is "each elem on one line"
|
||||
return (context.cend() - context.cbegin() >= 2)
|
||||
&& (*(context.cend() - 2) == "each elem on one line");
|
||||
}
|
||||
})
|
||||
).space_after_comma = true;
|
||||
|
||||
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")
|
||||
@ -346,8 +384,7 @@ TEST_CASE("serialization")
|
||||
|
||||
SECTION("multiline can have no space")
|
||||
{
|
||||
fancy_serializer_style style;
|
||||
style.set_old_multiline();
|
||||
fancy_serializer_style style = fancy_serializer_style::preset_multiline;
|
||||
style.space_after_colon = false;
|
||||
auto str = fancy_to_string({{"one", 1}}, style);
|
||||
CHECK(str == dedent(R"(
|
||||
@ -360,8 +397,7 @@ TEST_CASE("serialization")
|
||||
|
||||
SECTION("given width")
|
||||
{
|
||||
fancy_serializer_style style;
|
||||
style.set_old_multiline();
|
||||
fancy_serializer_style style = fancy_serializer_style::preset_multiline;
|
||||
auto str = fancy_to_string({"foo", 1, 2, 3, false, {{"one", 1}}}, style);
|
||||
CHECK(str == dedent(R"(
|
||||
[
|
||||
@ -378,10 +414,9 @@ TEST_CASE("serialization")
|
||||
|
||||
SECTION("given fill")
|
||||
{
|
||||
fancy_serializer_style style;
|
||||
fancy_serializer_style style = fancy_serializer_style::preset_multiline;
|
||||
style.indent_step = 1;
|
||||
style.indent_char = '\t';
|
||||
style.set_old_multiline();
|
||||
|
||||
auto str = fancy_to_string({"foo", 1, 2, 3, false, {{"one", 1}}}, style);
|
||||
CHECK(str ==
|
||||
@ -400,10 +435,9 @@ TEST_CASE("serialization")
|
||||
|
||||
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_char = 'X';
|
||||
style.set_old_multiline();
|
||||
|
||||
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")
|
||||
{
|
||||
fancy_serializer_style style;
|
||||
fancy_serializer_style style = fancy_serializer_style::preset_multiline;
|
||||
style.indent_step = 300;
|
||||
style.indent_char = 'X';
|
||||
style.set_old_multiline();
|
||||
|
||||
auto str = fancy_to_string({{"key", {{"key", 1}}}}, style);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user