From 5c9de17b6376ce94b1cdff4f4edbba798e9bfd08 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sat, 23 Nov 2019 22:08:53 -0500 Subject: rewrite of json report parsing added json.h with some utilities --- src/json.h | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 src/json.h (limited to 'src/json.h') diff --git a/src/json.h b/src/json.h new file mode 100644 index 00000000..d182f330 --- /dev/null +++ b/src/json.h @@ -0,0 +1,190 @@ +#ifndef MODORGANIZER_JSON_INCLUDED +#define MODORGANIZER_JSON_INCLUDED + +#include +#include +#include +#include +#include + +namespace json +{ + +class failed {}; + + +namespace details +{ + +QString typeName(const QJsonValue& v) +{ + if (v.isUndefined()) { + return "undefined"; + } else if (v.isNull()) { + return "null"; + } else if (v.isArray()) { + return "an array"; + } else if (v.isBool()) { + return "a bool"; + } else if (v.isDouble()) { + return "a double"; + } else if (v.isObject()) { + return "an object"; + } else if (v.isString()) { + return "a string"; + } else { + return "an unknown type"; + } +} + +QString typeName(const QJsonDocument& doc) +{ + if (doc.isEmpty()) { + return "empty"; + } else if (doc.isNull()) { + return "null"; + } else if (doc.isArray()) { + return "an array"; + } else if (doc.isObject()) { + return "an object"; + } else { + return "an unknown type"; + } +} + + +template +T convert(const QJsonValue& v) = delete; + +template <> +bool convert(const QJsonValue& v) +{ + if (!v.isBool()) { + throw failed(); + } + + return v.toBool(); +} + +template <> +QJsonObject convert(const QJsonValue& v) +{ + if (!v.isObject()) { + throw failed(); + } + + return v.toObject(); +} + +template <> +QString convert(const QJsonValue& v) +{ + if (!v.isString()) { + throw failed(); + } + + return v.toString(); +} + +template <> +QJsonArray convert(const QJsonValue& v) +{ + if (!v.isArray()) { + throw failed(); + } + + return v.toArray(); +} + +template <> +qint64 convert(const QJsonValue& v) +{ + if (!v.isDouble()) { + throw failed(); + } + + return static_cast(v.toDouble()); +} + +} // namespace + + +template +T convert(const QJsonValue& value, const char* what) +{ + try + { + return details::convert(value); + } + catch(failed&) + { + MOBase::log::error( + "'{}' is a {}, not a {}", + what, details::typeName(value), typeid(T).name); + + throw; + } +} + +template +T convertWarn(const QJsonValue& value, const char* what, T def={}) +{ + try + { + return details::convert(value); + } + catch(failed&) + { + MOBase::log::warn( + "'{}' is a {}, not a {}", + what, details::typeName(value), typeid(T).name()); + + return def; + } +} + +template +T get(const QJsonObject& o, const char* e) +{ + if (!o.contains(e)) { + MOBase::log::error("property '{}' is missing", e); + throw failed(); + } + + return convert(o[e], e); +} + +template +T getWarn(const QJsonObject& o, const char* e, T def={}) +{ + if (!o.contains(e)) { + MOBase::log::warn("property '{}' is missing", e); + return def; + } + + return convertWarn(o[e], e); +} + +template +T getOpt(const QJsonObject& o, const char* e, T def={}) +{ + if (!o.contains(e)) { + return def; + } + + return convertWarn(o[e], e); +} + + +template +void requireObject(const Value& v, const char* what) +{ + if (!v.isObject()) { + MOBase::log::error("{} is {}, not an object", what, details::typeName(v)); + throw failed(); + } +} + +} // namespace + +#endif // MODORGANIZER_JSON_INCLUDED -- cgit v1.3.1