From cecbcd19290114ae77961a4e8aedbaa10b5a5d2f Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 23 Dec 2016 14:45:32 +0100 Subject: [PATCH] Added operator `==` to compare `JsonVariant` and strings (issue #402) --- CHANGELOG.md | 5 + examples/ProgmemExample/ProgmemExample.ino | 7 +- examples/StringExample/StringExample.ino | 5 + include/ArduinoJson.hpp | 1 + include/ArduinoJson/JsonVariantBase.hpp | 60 ---------- .../ArduinoJson/JsonVariantComparisons.hpp | 106 ++++++++++++++++++ test/JsonVariant_Comparison_Tests.cpp | 36 +++++- 7 files changed, 158 insertions(+), 62 deletions(-) create mode 100644 include/ArduinoJson/JsonVariantComparisons.hpp diff --git a/CHANGELOG.md b/CHANGELOG.md index c0fdb8c7..74c01a04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ArduinoJson: change log ======================= +HEAD +---- + +* Added operator `==` to compare `JsonVariant` and strings (issue #402) + v5.7.3 ------ diff --git a/examples/ProgmemExample/ProgmemExample.ino b/examples/ProgmemExample/ProgmemExample.ino index a427e3e6..9ab3cf2b 100644 --- a/examples/ProgmemExample/ProgmemExample.ino +++ b/examples/ProgmemExample/ProgmemExample.ino @@ -39,9 +39,14 @@ void setup() { // JsonBuffer. root["sensor"] = F("gps"); + // You can compare the content of a JsonVariant to a Flash String + if (root["sensor"] == F("gps")) { + // ... + } + #else -#warning PROGMEM is only supported on AVR architecture +#warning PROGMEM is not supported on this platform #endif } diff --git a/examples/StringExample/StringExample.ino b/examples/StringExample/StringExample.ino index 46050329..359f64e3 100644 --- a/examples/StringExample/StringExample.ino +++ b/examples/StringExample/StringExample.ino @@ -48,6 +48,11 @@ void setup() { // WARNING: the content of the String will be duplicated in the JsonBuffer. root[String("sen") + "sor"] = String("gp") + "s"; + // You can compare the content of a JsonObject with a String + if (root["sensor"] == sensor) { + // ... + } + // Lastly, you can print the resulting JSON to a String String output; root.printTo(output); diff --git a/include/ArduinoJson.hpp b/include/ArduinoJson.hpp index 118f4dc7..b8281073 100644 --- a/include/ArduinoJson.hpp +++ b/include/ArduinoJson.hpp @@ -10,6 +10,7 @@ #include "ArduinoJson/DynamicJsonBuffer.hpp" #include "ArduinoJson/JsonArray.hpp" #include "ArduinoJson/JsonObject.hpp" +#include "ArduinoJson/JsonVariantComparisons.hpp" #include "ArduinoJson/StaticJsonBuffer.hpp" #include "ArduinoJson/Internals/JsonParserImpl.hpp" diff --git a/include/ArduinoJson/JsonVariantBase.hpp b/include/ArduinoJson/JsonVariantBase.hpp index a6f5d6db..00fd9338 100644 --- a/include/ArduinoJson/JsonVariantBase.hpp +++ b/include/ArduinoJson/JsonVariantBase.hpp @@ -97,64 +97,4 @@ class JsonVariantBase : public Internals::JsonPrintable { return static_cast(this); } }; - -template -inline bool operator==(const JsonVariantBase &left, TComparand right) { - return left.template as() == right; -} - -template -inline bool operator==(TComparand left, const JsonVariantBase &right) { - return left == right.template as(); -} - -template -inline bool operator!=(const JsonVariantBase &left, TComparand right) { - return left.template as() != right; -} - -template -inline bool operator!=(TComparand left, const JsonVariantBase &right) { - return left != right.template as(); -} - -template -inline bool operator<=(const JsonVariantBase &left, TComparand right) { - return left.template as() <= right; -} - -template -inline bool operator<=(TComparand left, const JsonVariantBase &right) { - return left <= right.template as(); -} - -template -inline bool operator>=(const JsonVariantBase &left, TComparand right) { - return left.template as() >= right; -} - -template -inline bool operator>=(TComparand left, const JsonVariantBase &right) { - return left >= right.template as(); -} - -template -inline bool operator<(const JsonVariantBase &left, TComparand right) { - return left.template as() < right; -} - -template -inline bool operator<(TComparand left, const JsonVariantBase &right) { - return left < right.template as(); -} - -template -inline bool operator>(const JsonVariantBase &left, TComparand right) { - return left.template as() > right; -} - -template -inline bool operator>(TComparand left, const JsonVariantBase &right) { - return left > right.template as(); -} } diff --git a/include/ArduinoJson/JsonVariantComparisons.hpp b/include/ArduinoJson/JsonVariantComparisons.hpp new file mode 100644 index 00000000..a0b79e9d --- /dev/null +++ b/include/ArduinoJson/JsonVariantComparisons.hpp @@ -0,0 +1,106 @@ +// Copyright Benoit Blanchon 2014-2016 +// MIT License +// +// Arduino JSON library +// https://github.com/bblanchon/ArduinoJson +// If you like this project, please add a star! + +#pragma once + +#include "Internals/StringFuncs.hpp" +#include "JsonVariantBase.hpp" +#include "TypeTraits/EnableIf.hpp" + +namespace ArduinoJson { +template +struct JsonVariantComparer { + static bool equals(const TVariant &variant, const TComparand &comparand) { + return variant.template as() == comparand; + } +}; + +template +struct JsonVariantComparer< + TVariant, TString, typename TypeTraits::EnableIf< + Internals::StringFuncs::has_equals>::type> { + static bool equals(const TVariant &variant, const TString &comparand) { + const char *value = variant.template as(); + return Internals::StringFuncs::equals(comparand, value); + } +}; + +template +inline bool operator==(const JsonVariantBase &variant, + TComparand comparand) { + typedef JsonVariantBase TVariant; + return JsonVariantComparer::equals(variant, comparand); +} + +template +inline bool operator==(TComparand comparand, + const JsonVariantBase &variant) { + typedef JsonVariantBase TVariant; + return JsonVariantComparer::equals(variant, comparand); +} + +template +inline bool operator!=(const JsonVariantBase &variant, + TComparand comparand) { + typedef JsonVariantBase TVariant; + return !JsonVariantComparer::equals(variant, comparand); +} + +template +inline bool operator!=(TComparand comparand, + const JsonVariantBase &variant) { + typedef JsonVariantBase TVariant; + return !JsonVariantComparer::equals(variant, comparand); +} + +template +inline bool operator<=(const JsonVariantBase &left, TComparand right) { + return left.template as() <= right; +} + +template +inline bool operator<=(TComparand comparand, + const JsonVariantBase &variant) { + return comparand <= variant.template as(); +} + +template +inline bool operator>=(const JsonVariantBase &variant, + TComparand comparand) { + return variant.template as() >= comparand; +} + +template +inline bool operator>=(TComparand comparand, + const JsonVariantBase &variant) { + return comparand >= variant.template as(); +} + +template +inline bool operator<(const JsonVariantBase &varian, + TComparand comparand) { + return varian.template as() < comparand; +} + +template +inline bool operator<(TComparand comparand, + const JsonVariantBase &variant) { + return comparand < variant.template as(); +} + +template +inline bool operator>(const JsonVariantBase &variant, + TComparand comparand) { + return variant.template as() > comparand; +} + +template +inline bool operator>(TComparand comparand, + const JsonVariantBase &variant) { + return comparand > variant.template as(); +} +} diff --git a/test/JsonVariant_Comparison_Tests.cpp b/test/JsonVariant_Comparison_Tests.cpp index bf66ad1e..e6030171 100644 --- a/test/JsonVariant_Comparison_Tests.cpp +++ b/test/JsonVariant_Comparison_Tests.cpp @@ -5,8 +5,8 @@ // https://github.com/bblanchon/ArduinoJson // If you like this project, please add a star! -#include #include +#include class JsonVariant_Comparison_Tests : public ::testing::Test { protected: @@ -92,3 +92,37 @@ TEST_F(JsonVariant_Comparison_Tests, ULong) { TEST_F(JsonVariant_Comparison_Tests, UShort) { testValue(122, 123, 124); } + +TEST_F(JsonVariant_Comparison_Tests, StringLiteral) { + DynamicJsonBuffer jsonBuffer; + JsonVariant variant = jsonBuffer.parse("\"hello\""); + + ASSERT_TRUE(variant == "hello"); + ASSERT_FALSE(variant != "hello"); + + ASSERT_TRUE(variant != "world"); + ASSERT_FALSE(variant == "world"); + + ASSERT_TRUE("hello" == variant); + ASSERT_FALSE("hello" != variant); + + ASSERT_TRUE("world" != variant); + ASSERT_FALSE("world" == variant); +} + +TEST_F(JsonVariant_Comparison_Tests, String) { + DynamicJsonBuffer jsonBuffer; + JsonVariant variant = jsonBuffer.parse("\"hello\""); + + ASSERT_TRUE(variant == std::string("hello")); + ASSERT_FALSE(variant != std::string("hello")); + + ASSERT_TRUE(variant != std::string("world")); + ASSERT_FALSE(variant == std::string("world")); + + ASSERT_TRUE(std::string("hello") == variant); + ASSERT_FALSE(std::string("hello") != variant); + + ASSERT_TRUE(std::string("world") != variant); + ASSERT_FALSE(std::string("world") == variant); +}