From 726f8be34165018648a7f4647748ebde403dbbce Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Sat, 26 Sep 2020 14:48:17 +0200 Subject: [PATCH] Added `operator|(JsonVariantConst, JsonVariantConst)` --- CHANGELOG.md | 1 + extras/tests/JsonVariant/or.cpp | 51 +++++++++++++++++++- src/ArduinoJson/Variant/VariantImpl.hpp | 5 ++ src/ArduinoJson/Variant/VariantOperators.hpp | 8 +-- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ec9cbc0..e961915b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ HEAD * Added `JsonDocument::overflowed()` which tells if the memory pool was too small (issue #1358) * Added `DeserializationError::EmptyInput` which tells if the input was empty * Added `DeserializationError::f_str()` which returns a `const __FlashStringHelper*` (issue #846) +* Added `operator|(JsonVariantConst, JsonVariantConst)` * Moved float convertion tables to PROGMEM * Fixed `JsonVariant::set((char*)0)` which returned false instead of true (issue #1368) * Fixed error `No such file or directory #include ` (issue #1381) diff --git a/extras/tests/JsonVariant/or.cpp b/extras/tests/JsonVariant/or.cpp index de1cc616..f28e2d8e 100644 --- a/extras/tests/JsonVariant/or.cpp +++ b/extras/tests/JsonVariant/or.cpp @@ -7,7 +7,7 @@ TEST_CASE("JsonVariant::operator|()") { DynamicJsonDocument doc(4096); - JsonVariant variant = doc.to(); + JsonVariant variant = doc["value"].to(); SECTION("undefined") { SECTION("undefined | const char*") { @@ -24,6 +24,27 @@ TEST_CASE("JsonVariant::operator|()") { bool result = variant | true; REQUIRE(result == true); } + + SECTION("undefined | ElementProxy") { + doc["array"][0] = 42; + + JsonVariantConst result = variant | doc["array"][0]; + REQUIRE(result == 42); + } + + SECTION("undefined | MemberProxy") { + doc["other"] = 42; + + JsonVariantConst result = variant | doc["other"]; + REQUIRE(result == 42); + } + + SECTION("ElementProxy | ElementProxy") { + doc["array"][0] = 42; + + JsonVariantConst result = doc["array"][1] | doc["array"][0]; + REQUIRE(result == 42); + } } SECTION("null") { @@ -43,6 +64,20 @@ TEST_CASE("JsonVariant::operator|()") { bool result = variant | true; REQUIRE(result == true); } + + SECTION("null | ElementProxy") { + doc["array"][0] = 42; + + JsonVariantConst result = variant | doc["array"][0]; + REQUIRE(result == 42); + } + + SECTION("null | MemberProxy") { + doc["other"] = 42; + + JsonVariantConst result = variant | doc["other"]; + REQUIRE(result == 42); + } } SECTION("int | const char*") { @@ -57,6 +92,20 @@ TEST_CASE("JsonVariant::operator|()") { REQUIRE(result == 42); } + SECTION("int | ElementProxy") { + variant.set(42); + doc["array"][0] = 666; + JsonVariantConst result = variant | doc["array"][0]; + REQUIRE(result == 42); + } + + SECTION("int | MemberProxy") { + variant.set(42); + doc["other"] = 666; + JsonVariantConst result = variant | doc["other"]; + REQUIRE(result == 42); + } + SECTION("int | int") { variant.set(0); int result = variant | 666; diff --git a/src/ArduinoJson/Variant/VariantImpl.hpp b/src/ArduinoJson/Variant/VariantImpl.hpp index cd347d1d..f773c244 100644 --- a/src/ArduinoJson/Variant/VariantImpl.hpp +++ b/src/ArduinoJson/Variant/VariantImpl.hpp @@ -139,4 +139,9 @@ template inline VariantRef VariantRef::getOrAddMember(const TString &key) const { return VariantRef(_pool, variantGetOrAddMember(_data, key, _pool)); } + +inline VariantConstRef operator|(VariantConstRef preferedValue, + VariantConstRef defaultValue) { + return preferedValue ? preferedValue : defaultValue; +} } // namespace ARDUINOJSON_NAMESPACE diff --git a/src/ArduinoJson/Variant/VariantOperators.hpp b/src/ArduinoJson/Variant/VariantOperators.hpp index 67a0f7c5..79379e81 100644 --- a/src/ArduinoJson/Variant/VariantOperators.hpp +++ b/src/ArduinoJson/Variant/VariantOperators.hpp @@ -19,7 +19,8 @@ template struct VariantOperators { // Returns the default value if the VariantRef is undefined of incompatible template - friend T operator|(const TVariant &variant, const T &defaultValue) { + friend typename enable_if::value, T>::type operator|( + const TVariant &variant, const T &defaultValue) { if (variant.template is()) return variant.template as(); else @@ -28,8 +29,9 @@ struct VariantOperators { // Returns the default value if the VariantRef is undefined of incompatible // Special case for string: null is treated as undefined - friend const char *operator|(const TVariant &variant, - const char *defaultValue) { + template + friend typename enable_if::value, T>::type operator|( + const TVariant &variant, T defaultValue) { const char *value = variant.template as(); return value ? value : defaultValue; }