Introduce fancy_serializer_style
This commit is contained in:
parent
e38b4e8031
commit
003f3e298b
@ -23,6 +23,13 @@
|
|||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct fancy_serializer_style
|
||||||
|
{
|
||||||
|
unsigned int indent_step = 0;
|
||||||
|
char indent_char = ' ';
|
||||||
|
};
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
///////////////////
|
///////////////////
|
||||||
@ -45,8 +52,9 @@ class fancy_serializer
|
|||||||
@param[in] s output stream to serialize to
|
@param[in] s output stream to serialize to
|
||||||
@param[in] ichar indentation character to use
|
@param[in] ichar indentation character to use
|
||||||
*/
|
*/
|
||||||
fancy_serializer(output_adapter_t<char> s, const char ichar)
|
fancy_serializer(output_adapter_t<char> s,
|
||||||
: o(std::move(s)), indent_char(ichar), indent_string(512, indent_char)
|
const fancy_serializer_style& st)
|
||||||
|
: o(std::move(s)), indent_string(512, st.indent_char), style(st)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// delete because of pointer members
|
// delete because of pointer members
|
||||||
@ -70,9 +78,8 @@ class fancy_serializer
|
|||||||
@param[in] indent_step the indent level
|
@param[in] indent_step the indent level
|
||||||
@param[in] current_indent the current indent level (only used internally)
|
@param[in] current_indent the current indent level (only used internally)
|
||||||
*/
|
*/
|
||||||
void dump(const BasicJsonType& val, const bool pretty_print,
|
void dump(const BasicJsonType& val,
|
||||||
const bool ensure_ascii,
|
const bool ensure_ascii,
|
||||||
const unsigned int indent_step,
|
|
||||||
const unsigned int current_indent = 0)
|
const unsigned int current_indent = 0)
|
||||||
{
|
{
|
||||||
switch (val.m_type)
|
switch (val.m_type)
|
||||||
@ -85,12 +92,12 @@ class fancy_serializer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print)
|
if (style.indent_step > 0)
|
||||||
{
|
{
|
||||||
o->write_characters("{\n", 2);
|
o->write_characters("{\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + style.indent_step;
|
||||||
if (JSON_UNLIKELY(indent_string.size() < new_indent))
|
if (JSON_UNLIKELY(indent_string.size() < new_indent))
|
||||||
{
|
{
|
||||||
indent_string.resize(indent_string.size() * 2, ' ');
|
indent_string.resize(indent_string.size() * 2, ' ');
|
||||||
@ -104,7 +111,7 @@ 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("\": ", 3);
|
o->write_characters("\": ", 3);
|
||||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
dump(i->second, ensure_ascii, new_indent);
|
||||||
o->write_characters(",\n", 2);
|
o->write_characters(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +122,7 @@ 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("\": ", 3);
|
o->write_characters("\": ", 3);
|
||||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
dump(i->second, ensure_ascii, new_indent);
|
||||||
|
|
||||||
o->write_character('\n');
|
o->write_character('\n');
|
||||||
o->write_characters(indent_string.c_str(), current_indent);
|
o->write_characters(indent_string.c_str(), current_indent);
|
||||||
@ -132,7 +139,7 @@ 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);
|
o->write_characters("\":", 2);
|
||||||
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
dump(i->second, ensure_ascii, current_indent);
|
||||||
o->write_character(',');
|
o->write_character(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +149,7 @@ 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);
|
o->write_characters("\":", 2);
|
||||||
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
dump(i->second, ensure_ascii, current_indent);
|
||||||
|
|
||||||
o->write_character('}');
|
o->write_character('}');
|
||||||
}
|
}
|
||||||
@ -158,12 +165,12 @@ class fancy_serializer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print)
|
if (style.indent_step > 0)
|
||||||
{
|
{
|
||||||
o->write_characters("[\n", 2);
|
o->write_characters("[\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + style.indent_step;
|
||||||
if (JSON_UNLIKELY(indent_string.size() < new_indent))
|
if (JSON_UNLIKELY(indent_string.size() < new_indent))
|
||||||
{
|
{
|
||||||
indent_string.resize(indent_string.size() * 2, ' ');
|
indent_string.resize(indent_string.size() * 2, ' ');
|
||||||
@ -174,14 +181,14 @@ class fancy_serializer
|
|||||||
i != val.m_value.array->cend() - 1; ++i)
|
i != val.m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o->write_characters(indent_string.c_str(), new_indent);
|
||||||
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
dump(*i, ensure_ascii, new_indent);
|
||||||
o->write_characters(",\n", 2);
|
o->write_characters(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(not val.m_value.array->empty());
|
assert(not val.m_value.array->empty());
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o->write_characters(indent_string.c_str(), new_indent);
|
||||||
dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
|
dump(val.m_value.array->back(), ensure_ascii, new_indent);
|
||||||
|
|
||||||
o->write_character('\n');
|
o->write_character('\n');
|
||||||
o->write_characters(indent_string.c_str(), current_indent);
|
o->write_characters(indent_string.c_str(), current_indent);
|
||||||
@ -195,13 +202,13 @@ class fancy_serializer
|
|||||||
for (auto i = val.m_value.array->cbegin();
|
for (auto i = val.m_value.array->cbegin();
|
||||||
i != val.m_value.array->cend() - 1; ++i)
|
i != val.m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
dump(*i, false, ensure_ascii, indent_step, current_indent);
|
dump(*i, ensure_ascii, current_indent);
|
||||||
o->write_character(',');
|
o->write_character(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(not val.m_value.array->empty());
|
assert(not val.m_value.array->empty());
|
||||||
dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
|
dump(val.m_value.array->back(), ensure_ascii, current_indent);
|
||||||
|
|
||||||
o->write_character(']');
|
o->write_character(']');
|
||||||
}
|
}
|
||||||
@ -266,24 +273,25 @@ class fancy_serializer
|
|||||||
/// the output of the fancy_serializer
|
/// the output of the fancy_serializer
|
||||||
output_adapter_t<char> o = nullptr;
|
output_adapter_t<char> o = nullptr;
|
||||||
|
|
||||||
/// the indentation character
|
|
||||||
const char indent_char;
|
|
||||||
/// the indentation string
|
/// the indentation string
|
||||||
string_t indent_string;
|
string_t indent_string;
|
||||||
|
|
||||||
/// Used for serializing "base" objects. Strings are sort of
|
/// Used for serializing "base" objects. Strings are sort of
|
||||||
/// counted in this, but not completely.
|
/// counted in this, but not completely.
|
||||||
primitive_serializer_t prim_serializer;
|
primitive_serializer_t prim_serializer;
|
||||||
|
|
||||||
|
/// Output style
|
||||||
|
fancy_serializer_style style;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
unsigned int indent_step, char indent_char)
|
fancy_serializer_style style)
|
||||||
{
|
{
|
||||||
// do the actual serialization
|
// do the actual serialization
|
||||||
detail::fancy_serializer<BasicJsonType> s(detail::output_adapter<char>(o), indent_char);
|
detail::fancy_serializer<BasicJsonType> s(detail::output_adapter<char>(o), style);
|
||||||
s.dump(j, indent_step > 0, false, indent_step);
|
s.dump(j, false, 0u);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10093,6 +10093,13 @@ class serializer
|
|||||||
|
|
||||||
namespace nlohmann
|
namespace nlohmann
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct fancy_serializer_style
|
||||||
|
{
|
||||||
|
unsigned int indent_step = 0;
|
||||||
|
char indent_char = ' ';
|
||||||
|
};
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
///////////////////
|
///////////////////
|
||||||
@ -10115,8 +10122,9 @@ class fancy_serializer
|
|||||||
@param[in] s output stream to serialize to
|
@param[in] s output stream to serialize to
|
||||||
@param[in] ichar indentation character to use
|
@param[in] ichar indentation character to use
|
||||||
*/
|
*/
|
||||||
fancy_serializer(output_adapter_t<char> s, const char ichar)
|
fancy_serializer(output_adapter_t<char> s,
|
||||||
: o(std::move(s)), indent_char(ichar), indent_string(512, indent_char)
|
const fancy_serializer_style& st)
|
||||||
|
: o(std::move(s)), indent_string(512, st.indent_char), style(st)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// delete because of pointer members
|
// delete because of pointer members
|
||||||
@ -10140,9 +10148,8 @@ class fancy_serializer
|
|||||||
@param[in] indent_step the indent level
|
@param[in] indent_step the indent level
|
||||||
@param[in] current_indent the current indent level (only used internally)
|
@param[in] current_indent the current indent level (only used internally)
|
||||||
*/
|
*/
|
||||||
void dump(const BasicJsonType& val, const bool pretty_print,
|
void dump(const BasicJsonType& val,
|
||||||
const bool ensure_ascii,
|
const bool ensure_ascii,
|
||||||
const unsigned int indent_step,
|
|
||||||
const unsigned int current_indent = 0)
|
const unsigned int current_indent = 0)
|
||||||
{
|
{
|
||||||
switch (val.m_type)
|
switch (val.m_type)
|
||||||
@ -10155,12 +10162,12 @@ class fancy_serializer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print)
|
if (style.indent_step > 0)
|
||||||
{
|
{
|
||||||
o->write_characters("{\n", 2);
|
o->write_characters("{\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + style.indent_step;
|
||||||
if (JSON_UNLIKELY(indent_string.size() < new_indent))
|
if (JSON_UNLIKELY(indent_string.size() < new_indent))
|
||||||
{
|
{
|
||||||
indent_string.resize(indent_string.size() * 2, ' ');
|
indent_string.resize(indent_string.size() * 2, ' ');
|
||||||
@ -10174,7 +10181,7 @@ 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("\": ", 3);
|
o->write_characters("\": ", 3);
|
||||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
dump(i->second, ensure_ascii, new_indent);
|
||||||
o->write_characters(",\n", 2);
|
o->write_characters(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10185,7 +10192,7 @@ 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("\": ", 3);
|
o->write_characters("\": ", 3);
|
||||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
dump(i->second, ensure_ascii, new_indent);
|
||||||
|
|
||||||
o->write_character('\n');
|
o->write_character('\n');
|
||||||
o->write_characters(indent_string.c_str(), current_indent);
|
o->write_characters(indent_string.c_str(), current_indent);
|
||||||
@ -10202,7 +10209,7 @@ 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);
|
o->write_characters("\":", 2);
|
||||||
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
dump(i->second, ensure_ascii, current_indent);
|
||||||
o->write_character(',');
|
o->write_character(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10212,7 +10219,7 @@ 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);
|
o->write_characters("\":", 2);
|
||||||
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
dump(i->second, ensure_ascii, current_indent);
|
||||||
|
|
||||||
o->write_character('}');
|
o->write_character('}');
|
||||||
}
|
}
|
||||||
@ -10228,12 +10235,12 @@ class fancy_serializer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print)
|
if (style.indent_step > 0)
|
||||||
{
|
{
|
||||||
o->write_characters("[\n", 2);
|
o->write_characters("[\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + style.indent_step;
|
||||||
if (JSON_UNLIKELY(indent_string.size() < new_indent))
|
if (JSON_UNLIKELY(indent_string.size() < new_indent))
|
||||||
{
|
{
|
||||||
indent_string.resize(indent_string.size() * 2, ' ');
|
indent_string.resize(indent_string.size() * 2, ' ');
|
||||||
@ -10244,14 +10251,14 @@ class fancy_serializer
|
|||||||
i != val.m_value.array->cend() - 1; ++i)
|
i != val.m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o->write_characters(indent_string.c_str(), new_indent);
|
||||||
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
dump(*i, ensure_ascii, new_indent);
|
||||||
o->write_characters(",\n", 2);
|
o->write_characters(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(not val.m_value.array->empty());
|
assert(not val.m_value.array->empty());
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o->write_characters(indent_string.c_str(), new_indent);
|
||||||
dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
|
dump(val.m_value.array->back(), ensure_ascii, new_indent);
|
||||||
|
|
||||||
o->write_character('\n');
|
o->write_character('\n');
|
||||||
o->write_characters(indent_string.c_str(), current_indent);
|
o->write_characters(indent_string.c_str(), current_indent);
|
||||||
@ -10265,13 +10272,13 @@ class fancy_serializer
|
|||||||
for (auto i = val.m_value.array->cbegin();
|
for (auto i = val.m_value.array->cbegin();
|
||||||
i != val.m_value.array->cend() - 1; ++i)
|
i != val.m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
dump(*i, false, ensure_ascii, indent_step, current_indent);
|
dump(*i, ensure_ascii, current_indent);
|
||||||
o->write_character(',');
|
o->write_character(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(not val.m_value.array->empty());
|
assert(not val.m_value.array->empty());
|
||||||
dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
|
dump(val.m_value.array->back(), ensure_ascii, current_indent);
|
||||||
|
|
||||||
o->write_character(']');
|
o->write_character(']');
|
||||||
}
|
}
|
||||||
@ -10336,24 +10343,25 @@ class fancy_serializer
|
|||||||
/// the output of the fancy_serializer
|
/// the output of the fancy_serializer
|
||||||
output_adapter_t<char> o = nullptr;
|
output_adapter_t<char> o = nullptr;
|
||||||
|
|
||||||
/// the indentation character
|
|
||||||
const char indent_char;
|
|
||||||
/// the indentation string
|
/// the indentation string
|
||||||
string_t indent_string;
|
string_t indent_string;
|
||||||
|
|
||||||
/// Used for serializing "base" objects. Strings are sort of
|
/// Used for serializing "base" objects. Strings are sort of
|
||||||
/// counted in this, but not completely.
|
/// counted in this, but not completely.
|
||||||
primitive_serializer_t prim_serializer;
|
primitive_serializer_t prim_serializer;
|
||||||
|
|
||||||
|
/// Output style
|
||||||
|
fancy_serializer_style style;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
unsigned int indent_step, char indent_char)
|
fancy_serializer_style style)
|
||||||
{
|
{
|
||||||
// do the actual serialization
|
// do the actual serialization
|
||||||
detail::fancy_serializer<BasicJsonType> s(detail::output_adapter<char>(o), indent_char);
|
detail::fancy_serializer<BasicJsonType> s(detail::output_adapter<char>(o), style);
|
||||||
s.dump(j, indent_step > 0, false, indent_step);
|
s.dump(j, false, 0u);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,11 +33,12 @@ SOFTWARE.
|
|||||||
|
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
using nlohmann::fancy_dump;
|
using nlohmann::fancy_dump;
|
||||||
|
using nlohmann::fancy_serializer_style;
|
||||||
|
|
||||||
std::string fancy_to_string(json j, unsigned int indent_step = 0, char indent_char = ' ')
|
std::string fancy_to_string(json j, fancy_serializer_style style = fancy_serializer_style())
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
fancy_dump(ss, j, indent_step, indent_char);
|
fancy_dump(ss, j, style);
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +79,9 @@ TEST_CASE("serialization")
|
|||||||
|
|
||||||
SECTION("given width")
|
SECTION("given width")
|
||||||
{
|
{
|
||||||
auto str = fancy_to_string({"foo", 1, 2, 3, false, {{"one", 1}}}, 4);
|
fancy_serializer_style style;
|
||||||
|
style.indent_step = 4;
|
||||||
|
auto str = fancy_to_string({"foo", 1, 2, 3, false, {{"one", 1}}}, style);
|
||||||
CHECK(str ==
|
CHECK(str ==
|
||||||
"[\n"
|
"[\n"
|
||||||
" \"foo\",\n"
|
" \"foo\",\n"
|
||||||
@ -95,7 +98,11 @@ TEST_CASE("serialization")
|
|||||||
|
|
||||||
SECTION("given fill")
|
SECTION("given fill")
|
||||||
{
|
{
|
||||||
auto str = fancy_to_string({"foo", 1, 2, 3, false, {{"one", 1}}}, 1, '\t');
|
fancy_serializer_style style;
|
||||||
|
style.indent_step = 1;
|
||||||
|
style.indent_char = '\t';
|
||||||
|
|
||||||
|
auto str = fancy_to_string({"foo", 1, 2, 3, false, {{"one", 1}}}, style);
|
||||||
CHECK(str ==
|
CHECK(str ==
|
||||||
"[\n"
|
"[\n"
|
||||||
"\t\"foo\",\n"
|
"\t\"foo\",\n"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user