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> template<typename BasicJsonType>
class fancy_serializer_stylizer class basic_fancy_serializer_stylizer
{ {
public: 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) : default_style(ds)
{} {}
fancy_serializer_stylizer() = delete; basic_fancy_serializer_stylizer() = default;
public: public:
const fancy_serializer_style& get_default_style() const const fancy_serializer_style& get_default_style() const
@ -51,8 +53,26 @@ class fancy_serializer_stylizer
return default_style; 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: private:
fancy_serializer_style default_style; fancy_serializer_style default_style;
std::map<string_t, fancy_serializer_style> key_styles;
}; };
namespace detail namespace detail
@ -64,7 +84,7 @@ namespace detail
template<typename BasicJsonType> template<typename BasicJsonType>
class fancy_serializer 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 primitive_serializer_t = primitive_serializer<BasicJsonType>;
using string_t = typename BasicJsonType::string_t; using string_t = typename BasicJsonType::string_t;
using number_float_t = typename BasicJsonType::number_float_t; using number_float_t = typename BasicJsonType::number_float_t;
@ -216,7 +236,8 @@ class fancy_serializer
o->write_character('\"'); o->write_character('\"');
prim_serializer.dump_escaped(*o, i->first, ensure_ascii); prim_serializer.dump_escaped(*o, i->first, ensure_ascii);
o->write_characters("\": ", 2 + newline_len); 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); o->write_characters(",\n", 1 + newline_len);
} }
@ -227,7 +248,8 @@ class fancy_serializer
o->write_character('\"'); o->write_character('\"');
prim_serializer.dump_escaped(*o, i->first, ensure_ascii); prim_serializer.dump_escaped(*o, i->first, ensure_ascii);
o->write_characters("\": ", 2 + newline_len); 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("\n", newline_len);
o->write_characters(indent_string.c_str(), old_indent); o->write_characters(indent_string.c_str(), old_indent);
@ -360,13 +382,20 @@ class fancy_serializer
template<typename BasicJsonType> template<typename BasicJsonType>
std::ostream& fancy_dump(std::ostream& o, const BasicJsonType& j, 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 // do the actual serialization
detail::fancy_serializer<BasicJsonType> s(detail::output_adapter<char>(o), stylizer); detail::fancy_serializer<BasicJsonType> s(detail::output_adapter<char>(o), stylizer);
s.dump(j, false); s.dump(j, false);
return o; 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 } // namespace nlohmann
/////////////////////// ///////////////////////

View File

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

View File

@ -34,6 +34,7 @@ SOFTWARE.
using nlohmann::json; using nlohmann::json;
using nlohmann::fancy_dump; using nlohmann::fancy_dump;
using nlohmann::fancy_serializer_style; 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 // 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 // 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(); 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") TEST_CASE("serialization")
{ {
SECTION("primitives") 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") SECTION("given width")
{ {
fancy_serializer_style style; fancy_serializer_style style;