diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-06-28 11:31:36 +0200 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-06-29 15:36:20 +0200 |
commit | 39cab886df1a50ea8e70504dff83cc77c6140bcb (patch) | |
tree | a940525ef248d52e6dc1eba942b066ad2f5570d0 /src | |
parent | 6045a6d15738b3104e34cc05a9c5624f3f98bd03 (diff) | |
download | justbuild-39cab886df1a50ea8e70504dff83cc77c6140bcb.tar.gz |
util: support abbreviating json
To an intended number of characters by leaving out the parts
after a given depth. As the correct depths has to be determined,
the JSON value is serialized several times; hence the method is
slow, but acceptable for the generation of error messages.
Diffstat (limited to 'src')
-rw-r--r-- | src/utils/cpp/json.hpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/utils/cpp/json.hpp b/src/utils/cpp/json.hpp index 471b4861..984208df 100644 --- a/src/utils/cpp/json.hpp +++ b/src/utils/cpp/json.hpp @@ -145,4 +145,58 @@ namespace detail { json, std::string(indent, ' '), until_depth, 0, "", depths); } +// \brief Dump json, replacing subexpressions at the given depths by "*". +// NOLINTNEXTLINE(misc-no-recursion) +[[nodiscard]] static inline auto TruncateJson(nlohmann::json const& json, + std::size_t depth) + -> std::string { + if (depth == 0) { + return "*"; + } + if (json.is_object()) { + std::size_t i{}; + std::ostringstream oss{}; + oss << '{'; + for (auto const& [key, value] : json.items()) { + oss << nlohmann::json(key).dump() << ":" + << TruncateJson(value, depth - 1) + << (++i == json.size() ? "" : ","); + } + oss << '}'; + gsl_EnsuresAudit(nlohmann::json::parse(oss.str()) == json); + return oss.str(); + } + if (json.is_array()) { + std::size_t i{}; + std::ostringstream oss{}; + oss << '['; + for (auto const& value : json) { + oss << TruncateJson(value, depth - 1) + << (++i == json.size() ? "" : ","); + } + oss << ']'; + gsl_EnsuresAudit(nlohmann::json::parse(oss.str()) == json); + return oss.str(); + } + return json.dump(); +} + +[[nodiscard]] static inline auto AbbreviateJson(nlohmann::json const& json, + std::size_t len) + -> std::string { + auto json_string = json.dump(); + if (json_string.size() <= len) { + return json_string; + } + std::size_t i = 1; + auto old_abbrev = TruncateJson(json, i); + auto new_abbrev = old_abbrev; + while (new_abbrev.size() <= len) { + old_abbrev = new_abbrev; + ++i; + new_abbrev = TruncateJson(json, i); + } + return old_abbrev; +} + #endif // INCLUDED_SRC_UTILS_CPP_JSON_HPP |