♻️ reorganize PR

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-07-01 18:01:53 +02:00
parent 699a239067
commit 9df2375e91
12 changed files with 336 additions and 28 deletions
+52 -4
View File
@@ -5382,27 +5382,75 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC
NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-cpp)
{
bool pretty = false;
// -1 means compact output (dump()); any value >= 0 means pretty-printed
// output with that many spaces (or indent_char) per level (dump(indent, indent_char)).
int indent = -1;
char indent_char = ' ';
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
auto it = ctx.begin();
if (it != ctx.end() && *it == '#')
const auto end = ctx.end();
constexpr auto is_align = [](char c)
{
return c == '<' || c == '>' || c == '^';
};
// [[fill] align] - repurposed here to pick a custom indent character,
// e.g. "{:.>#4}" pretty-prints with '.' as the indent character
if (it != end && it + 1 != end && is_align(it[1]))
{
indent_char = *it;
it += 2;
}
else if (it != end && is_align(*it))
{
++it;
}
// ['#'] - "alternate form", used here to request pretty-printing
bool pretty = false;
if (it != end && *it == '#')
{
pretty = true;
++it;
}
if (it != ctx.end() && *it != '}')
// [width] - repurposed here to pick the indent size for pretty-printing,
// e.g. "{:2}" or "{:#2}" pretty-print with an indent of 2; a width without
// '#' implies pretty-printing since an indent otherwise has no meaning
if (it != end && *it >= '1' && *it <= '9')
{
indent = 0;
while (it != end && *it >= '0' && *it <= '9')
{
indent = (indent * 10) + (*it - '0');
++it;
}
}
else if (pretty)
{
indent = 4;
}
// sign, the '0' flag, precision, locale-specific formatting ('L'), dynamic
// width/precision ("{...}"), and type characters all have no meaning for
// JSON values; none of them are consumed above, so they all end up rejected
// by this single check along with any other unrecognized trailing spec.
if (it != end && *it != '}')
{
JSON_THROW(format_error("invalid format args for nlohmann::json"));
}
return it;
}
template<typename FormatContext>
auto format(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j, FormatContext& ctx) const -> decltype(ctx.out())
{
const auto dumped = pretty ? j.dump(4) : j.dump();
// dump()'s own default (indent = -1) already means compact output, so this
// covers both the compact and pretty-printed cases without a branch.
const auto dumped = j.dump(indent, indent_char);
return std::copy(dumped.begin(), dumped.end(), ctx.out());
}
};