Can style subobjects of a object differently, by key

This commit is contained in:
Evan Driscoll 2018-06-02 23:10:28 -05:00
parent 7fa4431474
commit 186c7df25a
4 changed files with 116 additions and 16 deletions

View File

@ -36,14 +36,16 @@ struct fancy_serializer_style
};
template<typename BasicJsonType>
class fancy_serializer_stylizer
class basic_fancy_serializer_stylizer
{
public:
fancy_serializer_stylizer(fancy_serializer_style const& ds)
using string_t = typename BasicJsonType::string_t;
basic_fancy_serializer_stylizer(fancy_serializer_style const& ds)
: default_style(ds)
{}
fancy_serializer_stylizer() = delete;
basic_fancy_serializer_stylizer() = default;
public:
const fancy_serializer_style& get_default_style() const
@ -51,8 +53,26 @@ class fancy_serializer_stylizer
return default_style;
}
fancy_serializer_style& get_default_style()
{
return default_style;
}
const fancy_serializer_style& get_style(const string_t& j) const
{
auto iter = key_styles.find(j);
return iter == key_styles.end() ? default_style : iter->second;
}
fancy_serializer_style& get_or_insert_style(const string_t& j)
{
return key_styles[j];
}
private:
fancy_serializer_style default_style;
std::map<string_t, fancy_serializer_style> key_styles;
};
namespace detail
@ -64,7 +84,7 @@ namespace detail
template<typename BasicJsonType>
class fancy_serializer
{
using stylizer_t = fancy_serializer_stylizer<BasicJsonType>;
using stylizer_t = basic_fancy_serializer_stylizer<BasicJsonType>;
using primitive_serializer_t = primitive_serializer<BasicJsonType>;
using string_t = typename BasicJsonType::string_t;
using number_float_t = typename BasicJsonType::number_float_t;
@ -216,7 +236,8 @@ class fancy_serializer
o->write_character('\"');
prim_serializer.dump_escaped(*o, i->first, ensure_ascii);
o->write_characters("\": ", 2 + newline_len);
dump(i->second, ensure_ascii, depth + 1, active_style);
auto new_style = &stylizer.get_style(i->first);
dump(i->second, ensure_ascii, depth + 1, new_style);
o->write_characters(",\n", 1 + newline_len);
}
@ -227,7 +248,8 @@ class fancy_serializer
o->write_character('\"');
prim_serializer.dump_escaped(*o, i->first, ensure_ascii);
o->write_characters("\": ", 2 + newline_len);
dump(i->second, ensure_ascii, depth + 1, active_style);
auto new_style = &stylizer.get_style(i->first);
dump(i->second, ensure_ascii, depth + 1, new_style);
o->write_characters("\n", newline_len);
o->write_characters(indent_string.c_str(), old_indent);
@ -360,13 +382,20 @@ class fancy_serializer
template<typename BasicJsonType>
std::ostream& fancy_dump(std::ostream& o, const BasicJsonType& j,
fancy_serializer_style style)
basic_fancy_serializer_stylizer<BasicJsonType> const& stylizer)
{
fancy_serializer_stylizer<BasicJsonType> stylizer(style);
// do the actual serialization
detail::fancy_serializer<BasicJsonType> s(detail::output_adapter<char>(o), stylizer);
s.dump(j, false);
return o;
}
template<typename BasicJsonType>
std::ostream& fancy_dump(std::ostream& o, const BasicJsonType& j,
fancy_serializer_style style)
{
basic_fancy_serializer_stylizer<BasicJsonType> stylizer(style);
return fancy_dump(o, j, stylizer);
}
}

View File

@ -7624,6 +7624,8 @@ class basic_json
/// @}
};
using fancy_serializer_stylizer = basic_fancy_serializer_stylizer<json>;
} // namespace nlohmann
///////////////////////

View File

@ -10106,14 +10106,16 @@ struct fancy_serializer_style
};
template<typename BasicJsonType>
class fancy_serializer_stylizer
class basic_fancy_serializer_stylizer
{
public:
fancy_serializer_stylizer(fancy_serializer_style const& ds)
using string_t = typename BasicJsonType::string_t;
basic_fancy_serializer_stylizer(fancy_serializer_style const& ds)
: default_style(ds)
{}
fancy_serializer_stylizer() = delete;
basic_fancy_serializer_stylizer() = default;
public:
const fancy_serializer_style& get_default_style() const
@ -10121,8 +10123,26 @@ class fancy_serializer_stylizer
return default_style;
}
fancy_serializer_style& get_default_style()
{
return default_style;
}
const fancy_serializer_style& get_style(const string_t& j) const
{
auto iter = key_styles.find(j);
return iter == key_styles.end() ? default_style : iter->second;
}
fancy_serializer_style& get_or_insert_style(const string_t& j)
{
return key_styles[j];
}
private:
fancy_serializer_style default_style;
std::map<string_t, fancy_serializer_style> key_styles;
};
namespace detail
@ -10134,7 +10154,7 @@ namespace detail
template<typename BasicJsonType>
class fancy_serializer
{
using stylizer_t = fancy_serializer_stylizer<BasicJsonType>;
using stylizer_t = basic_fancy_serializer_stylizer<BasicJsonType>;
using primitive_serializer_t = primitive_serializer<BasicJsonType>;
using string_t = typename BasicJsonType::string_t;
using number_float_t = typename BasicJsonType::number_float_t;
@ -10286,7 +10306,8 @@ class fancy_serializer
o->write_character('\"');
prim_serializer.dump_escaped(*o, i->first, ensure_ascii);
o->write_characters("\": ", 2 + newline_len);
dump(i->second, ensure_ascii, depth + 1, active_style);
auto new_style = &stylizer.get_style(i->first);
dump(i->second, ensure_ascii, depth + 1, new_style);
o->write_characters(",\n", 1 + newline_len);
}
@ -10297,7 +10318,8 @@ class fancy_serializer
o->write_character('\"');
prim_serializer.dump_escaped(*o, i->first, ensure_ascii);
o->write_characters("\": ", 2 + newline_len);
dump(i->second, ensure_ascii, depth + 1, active_style);
auto new_style = &stylizer.get_style(i->first);
dump(i->second, ensure_ascii, depth + 1, new_style);
o->write_characters("\n", newline_len);
o->write_characters(indent_string.c_str(), old_indent);
@ -10430,15 +10452,22 @@ class fancy_serializer
template<typename BasicJsonType>
std::ostream& fancy_dump(std::ostream& o, const BasicJsonType& j,
fancy_serializer_style style)
basic_fancy_serializer_stylizer<BasicJsonType> const& stylizer)
{
fancy_serializer_stylizer<BasicJsonType> stylizer(style);
// do the actual serialization
detail::fancy_serializer<BasicJsonType> s(detail::output_adapter<char>(o), stylizer);
s.dump(j, false);
return o;
}
template<typename BasicJsonType>
std::ostream& fancy_dump(std::ostream& o, const BasicJsonType& j,
fancy_serializer_style style)
{
basic_fancy_serializer_stylizer<BasicJsonType> stylizer(style);
return fancy_dump(o, j, stylizer);
}
}
// #include <nlohmann/detail/json_ref.hpp>
@ -18811,6 +18840,8 @@ class basic_json
/// @}
};
using fancy_serializer_stylizer = basic_fancy_serializer_stylizer<json>;
} // namespace nlohmann
///////////////////////

View File

@ -34,6 +34,7 @@ SOFTWARE.
using nlohmann::json;
using nlohmann::fancy_dump;
using nlohmann::fancy_serializer_style;
using nlohmann::fancy_serializer_stylizer;
// Chops off the first line (if empty, but if it *isn't* empty you're
// probably using this wrong), measures the leading indent on the
@ -77,6 +78,13 @@ std::string fancy_to_string(json j, fancy_serializer_style style = fancy_seriali
return ss.str();
}
std::string fancy_to_string(json j, fancy_serializer_stylizer stylizer)
{
std::stringstream ss;
fancy_dump(ss, j, stylizer);
return ss.str();
}
TEST_CASE("serialization")
{
SECTION("primitives")
@ -220,6 +228,36 @@ TEST_CASE("serialization")
}
}
SECTION("changing styles")
{
SECTION("can style objects of a key differently")
{
fancy_serializer_stylizer stylizer;
stylizer.get_default_style().indent_step = 4;
stylizer.get_or_insert_style("one line").indent_step = 0;
auto str = fancy_to_string(
{
{
"one line", {1, 2}
},
{
"two lines", {1, 2}
}
},
stylizer);
CHECK(str == dedent(R"(
{
"one line": [1,2],
"two lines": [
1,
2
]
})"));
}
}
SECTION("given width")
{
fancy_serializer_style style;