It's now possible to limit the size of strings

This commit is contained in:
Evan Driscoll 2018-06-02 02:09:04 -05:00
parent 003f3e298b
commit d54f4653ed
3 changed files with 182 additions and 2 deletions

View File

@ -28,6 +28,8 @@ struct fancy_serializer_style
{
unsigned int indent_step = 0;
char indent_char = ' ';
unsigned int strings_maximum_length = 0;
};
namespace detail
@ -219,7 +221,61 @@ class fancy_serializer
case value_t::string:
{
o->write_character('\"');
prim_serializer.dump_escaped(*o, *val.m_value.string, ensure_ascii);
if (style.strings_maximum_length == 0)
{
prim_serializer.dump_escaped(*o, *val.m_value.string, ensure_ascii);
}
else
{
std::stringstream ss;
nlohmann::detail::output_adapter<char> o_string(ss);
nlohmann::detail::output_adapter_t<char> oo_string = o_string;
prim_serializer.dump_escaped(*oo_string, *val.m_value.string, ensure_ascii);
std::string str = ss.str();
if (str.size() <= style.strings_maximum_length)
{
o->write_characters(str.c_str(), str.size());
}
else
{
const unsigned start_len = [](unsigned int maxl)
{
if (maxl <= 3)
{
// There is only room for the ellipsis,
// no characters from the string
return 0u;
}
else if (maxl <= 5)
{
// With four allowed characters, we add in the
// first from the string. With five, we add in
// the *last* instead, so still just one at
// the start.
return 1u;
}
else
{
// We subtract three for the ellipsis
// and one for the last character.
return maxl - 4;
}
}(style.strings_maximum_length);
const unsigned end_len =
style.strings_maximum_length >= 5 ? 1 : 0;
const unsigned ellipsis_length =
style.strings_maximum_length >= 3
? 3
: style.strings_maximum_length;
o->write_characters(str.c_str(), start_len);
o->write_characters("...", ellipsis_length);
o->write_characters(str.c_str() + str.size() - end_len, end_len);
}
}
o->write_character('\"');
return;
}

View File

@ -10098,6 +10098,8 @@ struct fancy_serializer_style
{
unsigned int indent_step = 0;
char indent_char = ' ';
unsigned int strings_maximum_length = 0;
};
namespace detail
@ -10289,7 +10291,61 @@ class fancy_serializer
case value_t::string:
{
o->write_character('\"');
prim_serializer.dump_escaped(*o, *val.m_value.string, ensure_ascii);
if (style.strings_maximum_length == 0)
{
prim_serializer.dump_escaped(*o, *val.m_value.string, ensure_ascii);
}
else
{
std::stringstream ss;
nlohmann::detail::output_adapter<char> o_string(ss);
nlohmann::detail::output_adapter_t<char> oo_string = o_string;
prim_serializer.dump_escaped(*oo_string, *val.m_value.string, ensure_ascii);
std::string str = ss.str();
if (str.size() <= style.strings_maximum_length)
{
o->write_characters(str.c_str(), str.size());
}
else
{
const unsigned start_len = [](unsigned int maxl)
{
if (maxl <= 3)
{
// There is only room for the ellipsis,
// no characters from the string
return 0u;
}
else if (maxl <= 5)
{
// With four allowed characters, we add in the
// first from the string. With five, we add in
// the *last* instead, so still just one at
// the start.
return 1u;
}
else
{
// We subtract three for the ellipsis
// and one for the last character.
return maxl - 4;
}
}(style.strings_maximum_length);
const unsigned end_len =
style.strings_maximum_length >= 5 ? 1 : 0;
const unsigned ellipsis_length =
style.strings_maximum_length >= 3
? 3
: style.strings_maximum_length;
o->write_characters(str.c_str(), start_len);
o->write_characters("...", ellipsis_length);
o->write_characters(str.c_str() + str.size() - end_len, end_len);
}
}
o->write_character('\"');
return;
}

View File

@ -77,6 +77,74 @@ TEST_CASE("serialization")
}
}
SECTION("strings")
{
SECTION("long strings usually print")
{
auto str = fancy_to_string(
"The quick brown fox jumps over the lazy brown dog");
CHECK(str ==
"\"The quick brown fox jumps over the lazy brown dog\"");
}
SECTION("long strings can be shortened")
{
fancy_serializer_style style;
style.strings_maximum_length = 10;
auto str = fancy_to_string(
"The quick brown fox jumps over the lazy brown dog",
style);
CHECK(str == "\"The qu...g\"");
}
SECTION("requesting extremely short strings limits what is included")
{
const char* const quick = "The quick brown fox jumps over the lazy brown dog";
std::pair<unsigned, const char*> tests[] =
{
{5, "\"T...g\""},
{4, "\"T...\""},
{3, "\"...\""},
{2, "\"..\""},
{1, "\".\""},
};
for (auto test : tests)
{
fancy_serializer_style style;
style.strings_maximum_length = test.first;
auto str = fancy_to_string(quick, style);
CHECK(str == test.second);
}
}
SECTION("But you cannot ask for a length of zero; that means unlimited")
{
fancy_serializer_style style;
style.strings_maximum_length = 0;
auto str = fancy_to_string(
"The quick brown fox jumps over the lazy brown dog",
style);
CHECK(str ==
"\"The quick brown fox jumps over the lazy brown dog\"");
}
SECTION("\"Limiting\" to something long doesn't do anything")
{
fancy_serializer_style style;
style.strings_maximum_length = 100;
auto str = fancy_to_string(
"The quick brown fox jumps over the lazy brown dog",
style);
CHECK(str ==
"\"The quick brown fox jumps over the lazy brown dog\"");
}
}
SECTION("given width")
{
fancy_serializer_style style;