summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2022-06-28 11:31:36 +0200
committerKlaus Aehlig <klaus.aehlig@huawei.com>2022-06-29 15:36:20 +0200
commit39cab886df1a50ea8e70504dff83cc77c6140bcb (patch)
treea940525ef248d52e6dc1eba942b066ad2f5570d0 /src
parent6045a6d15738b3104e34cc05a9c5624f3f98bd03 (diff)
downloadjustbuild-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.hpp54
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