From b38d48e5bd2764568539089b248d0c3683783aa8 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 13 Jul 2019 19:54:08 +0900 Subject: converters.h: more comments; documented addParam<>() [skip ci] --- lib/converters.h | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'lib/converters.h') diff --git a/lib/converters.h b/lib/converters.h index af2be645..5f00dc43 100644 --- a/lib/converters.h +++ b/lib/converters.h @@ -107,6 +107,10 @@ namespace QMatrixClient return JsonConverter::load(jd); } + // Convenience fromJson() overloads that deduce T instead of requiring + // the coder to explicitly type it. They still enforce the + // overwrite-everything semantics of fromJson(), unlike fillFromJson() + template inline void fromJson(const QJsonValue& jv, T& pod) { @@ -357,7 +361,8 @@ namespace QMatrixClient q.addQueryItem(it.key(), it.value().toString()); } - // This one is for types that don't have isEmpty() + // This one is for types that don't have isEmpty() and for all types + // when Force is true template struct AddNode { @@ -369,7 +374,7 @@ namespace QMatrixClient } }; - // This one is for types that have isEmpty() + // This one is for types that have isEmpty() when Force is false template struct AddNode().isEmpty())> @@ -420,6 +425,29 @@ namespace QMatrixClient static constexpr bool IfNotEmpty = false; + /*! Add a key-value pair to QJsonObject or QUrlQuery + * + * Adds a key-value pair(s) specified by \p key and \p value to + * \p container, optionally (in case IfNotEmpty is passed for the first + * template parameter) taking into account the value "emptiness". + * With IfNotEmpty, \p value is NOT added to the container if and only if: + * - it has a method `isEmpty()` and `value.isEmpty() == true`, or + * - it's an `Omittable<>` and `value.omitted() == true`. + * + * If \p container is a QUrlQuery, an attempt to fit \p value into it is + * made as follows: + * - if \p value is a QJsonObject, \p key is ignored and pairs from \p value + * are copied to \p container, assuming that the value in each pair + * is a string; + * - if \p value is a QStringList, it is "exploded" into a list of key-value + * pairs with key equal to \p key and value taken from each list item; + * - if \p value is a bool, its OpenAPI (i.e. JSON) representation is added + * to the query (`true` or `false`, respectively). + * + * \tparam Force add the pair even if the value is empty. This is true + * by default; passing IfNotEmpty or false for this parameter + * enables emptiness checks as described above + */ template inline void addParam(ContT& container, const QString& key, ValT&& value) { -- cgit v1.2.3 From 26bc529ec86dce5478ab37222a27902af7f0dd5a Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 13 Jul 2019 19:57:46 +0900 Subject: converters.h: fallback to intrusive toJson() for JsonObjectConverter; general improvements Single-argument fromJson>() now works as well. --- lib/converters.h | 53 +++++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 24 deletions(-) (limited to 'lib/converters.h') diff --git a/lib/converters.h b/lib/converters.h index 5f00dc43..36b7ff15 100644 --- a/lib/converters.h +++ b/lib/converters.h @@ -60,8 +60,8 @@ namespace QMatrixClient template struct JsonObjectConverter { - static void dumpTo(QJsonObject& jo, const T& pod) { jo = pod; } - static void fillFrom(const QJsonObject& jo, T& pod) { pod = jo; } + static void dumpTo(QJsonObject& jo, const T& pod) { jo = pod.toJson(); } + static void fillFrom(const QJsonObject& jo, T& pod) { pod = T(jo); } }; template @@ -89,14 +89,16 @@ namespace QMatrixClient return JsonConverter::dump(pod); } + inline auto toJson(const QJsonObject& jo) { return jo; } + template - inline auto fillJson(QJsonObject& json, const T& data) + inline void fillJson(QJsonObject& json, const T& data) { JsonObjectConverter::dumpTo(json, data); } template - inline auto fromJson(const QJsonValue& jv) + inline T fromJson(const QJsonValue& jv) { return JsonConverter::load(jv); } @@ -114,8 +116,7 @@ namespace QMatrixClient template inline void fromJson(const QJsonValue& jv, T& pod) { - if (!jv.isUndefined()) - pod = fromJson(jv); + pod = jv.isUndefined() ? T() : fromJson(jv); } template @@ -124,21 +125,13 @@ namespace QMatrixClient pod = fromJson(jd); } - // Unfolds Omittable<> - template - inline void fromJson(const QJsonValue& jv, Omittable& pod) - { - if (jv.isUndefined()) - pod = none; - else - pod = fromJson(jv); - } - template inline void fillFromJson(const QJsonValue& jv, T& pod) { if (jv.isObject()) JsonObjectConverter::fillFrom(jv.toObject(), pod); + else if (!jv.isUndefined()) + pod = fromJson(jv); } // JsonConverter<> specialisations @@ -224,6 +217,21 @@ namespace QMatrixClient static QVariant load(const QJsonValue& jv); }; + template + struct JsonConverter> + { + static QJsonValue dump(const Omittable& from) + { + return from.omitted() ? QJsonValue() : toJson(from.value()); + } + static Omittable load(const QJsonValue& jv) + { + if (jv.isUndefined()) + return none; + return fromJson(jv); + } + }; + template struct JsonArrayConverter @@ -384,23 +392,20 @@ namespace QMatrixClient ForwardedT&& value) { if (!value.isEmpty()) - AddNode::impl(container, - key, std::forward(value)); + addTo(container, key, std::forward(value)); } }; - // This is a special one that unfolds Omittable<> - template - struct AddNode, Force> + // This one unfolds Omittable<> (also only when Force is false) + template + struct AddNode, false> { template static void impl(ContT& container, const QString& key, const OmittableT& value) { if (!value.omitted()) - AddNode::impl(container, key, value.value()); - else if (Force) // Edge case, no value but must put something - AddNode::impl(container, key, QString{}); + addTo(container, key, value.value()); } }; -- cgit v1.2.3