Added DeserializationError::code() to be used in switch statements (closes #846)

This commit is contained in:
Benoit Blanchon
2018-11-13 14:31:53 +01:00
parent 5eee947ffe
commit 0a97d4c825
3 changed files with 132 additions and 16 deletions

View File

@ -9,7 +9,8 @@ HEAD
* Replaced `T JsonArray::get<T>(i)` with `JsonVariant JsonArray::get(i)` * Replaced `T JsonArray::get<T>(i)` with `JsonVariant JsonArray::get(i)`
* Replaced `T JsonObject::get<T>(k)` with `JsonVariant JsonObject::get(k)` * Replaced `T JsonObject::get<T>(k)` with `JsonVariant JsonObject::get(k)`
* Added `JSON_STRING_SIZE()` * Added `JSON_STRING_SIZE()`
* Replacing or removing a value now releases the memory. * Replacing or removing a value now releases the memory
* Added `DeserializationError::code()` to be used in switch statements (issue #846)
v6.5.0-beta (2018-10-13) v6.5.0-beta (2018-10-13)
----------- -----------

View File

@ -11,6 +11,10 @@
namespace ARDUINOJSON_NAMESPACE { namespace ARDUINOJSON_NAMESPACE {
class DeserializationError { class DeserializationError {
// safe bool idiom
typedef void (DeserializationError::*bool_type)() const;
void safeBoolHelper() const {}
public: public:
enum Code { enum Code {
Ok, Ok,
@ -22,26 +26,52 @@ class DeserializationError {
}; };
DeserializationError() {} DeserializationError() {}
DeserializationError(Code code) : _code(code) {} DeserializationError(Code c) : _code(c) {}
friend bool operator==(const DeserializationError& err, Code code) { // Compare with DeserializationError
return err._code == code; friend bool operator==(const DeserializationError& lhs,
const DeserializationError& rhs) {
return lhs._code == rhs._code;
}
friend bool operator!=(const DeserializationError& lhs,
const DeserializationError& rhs) {
return lhs._code != rhs._code;
} }
friend bool operator==(Code code, const DeserializationError& err) { // Compare with Code
return err._code == code; friend bool operator==(const DeserializationError& lhs, Code rhs) {
return lhs._code == rhs;
}
friend bool operator==(Code lhs, const DeserializationError& rhs) {
return lhs == rhs._code;
}
friend bool operator!=(const DeserializationError& lhs, Code rhs) {
return lhs._code != rhs;
}
friend bool operator!=(Code lhs, const DeserializationError& rhs) {
return lhs != rhs._code;
} }
friend bool operator!=(const DeserializationError& err, Code code) { // Behaves like a bool
return err._code != code; operator bool_type() const {
return _code != Ok ? &DeserializationError::safeBoolHelper : 0;
}
friend bool operator==(bool value, const DeserializationError& err) {
return static_cast<bool>(err) == value;
}
friend bool operator==(const DeserializationError& err, bool value) {
return static_cast<bool>(err) == value;
}
friend bool operator!=(bool value, const DeserializationError& err) {
return static_cast<bool>(err) != value;
}
friend bool operator!=(const DeserializationError& err, bool value) {
return static_cast<bool>(err) != value;
} }
friend bool operator!=(Code code, const DeserializationError& err) { // Returns internal enum, useful for switch statement
return err._code != code; Code code() const {
} return _code;
operator bool() const {
return _code != Ok;
} }
const char* c_str() const { const char* c_str() const {

View File

@ -10,7 +10,15 @@ void testStringification(DeserializationError error, std::string expected) {
} }
void testBoolification(DeserializationError error, bool expected) { void testBoolification(DeserializationError error, bool expected) {
// DeserializationError on left-hand side
CHECK(error == expected); CHECK(error == expected);
CHECK(error != !expected);
CHECK(!error == !expected);
// DeserializationError on right-hand side
CHECK(expected == error);
CHECK(!expected != error);
CHECK(!expected == !error);
} }
#define TEST_STRINGIFICATION(symbol) \ #define TEST_STRINGIFICATION(symbol) \
@ -38,15 +46,92 @@ TEST_CASE("DeserializationError") {
TEST_BOOLIFICATION(NotSupported, true); TEST_BOOLIFICATION(NotSupported, true);
} }
SECTION("ostream code") { SECTION("ostream DeserializationError") {
std::stringstream s; std::stringstream s;
s << DeserializationError(DeserializationError::InvalidInput); s << DeserializationError(DeserializationError::InvalidInput);
REQUIRE(s.str() == "InvalidInput"); REQUIRE(s.str() == "InvalidInput");
} }
SECTION("ostream code") { SECTION("ostream DeserializationError::Code") {
std::stringstream s; std::stringstream s;
s << DeserializationError::InvalidInput; s << DeserializationError::InvalidInput;
REQUIRE(s.str() == "InvalidInput"); REQUIRE(s.str() == "InvalidInput");
} }
SECTION("out of range") {
int code = 666;
DeserializationError err(
*reinterpret_cast<DeserializationError::Code*>(&code));
REQUIRE(err.c_str() == std::string("???"));
}
SECTION("switch") {
DeserializationError err = DeserializationError::InvalidInput;
switch (err.code()) {
case DeserializationError::InvalidInput:
SUCCEED();
break;
default:
FAIL();
break;
}
}
SECTION("Comparisons") {
DeserializationError invalidInput(DeserializationError::InvalidInput);
DeserializationError ok(DeserializationError::Ok);
SECTION("DeserializationError == bool") {
REQUIRE(invalidInput == true);
REQUIRE(ok == false);
}
SECTION("bool == DeserializationError") {
REQUIRE(true == invalidInput);
REQUIRE(false == ok);
}
SECTION("DeserializationError != bool") {
REQUIRE(invalidInput != false);
REQUIRE(ok != true);
}
SECTION("bool != DeserializationError") {
REQUIRE(false != invalidInput);
REQUIRE(true != ok);
}
SECTION("Negations") {
REQUIRE(!invalidInput == false);
REQUIRE(!ok == true);
}
SECTION("DeserializationError == Code") {
REQUIRE(invalidInput == DeserializationError::InvalidInput);
REQUIRE(ok == DeserializationError::Ok);
}
SECTION("Code == DeserializationError") {
REQUIRE(DeserializationError::InvalidInput == invalidInput);
REQUIRE(DeserializationError::Ok == ok);
}
SECTION("DeserializationError != Code") {
REQUIRE(invalidInput != DeserializationError::Ok);
REQUIRE(ok != DeserializationError::InvalidInput);
}
SECTION("Code != DeserializationError") {
REQUIRE(DeserializationError::Ok != invalidInput);
REQUIRE(DeserializationError::InvalidInput != ok);
}
SECTION("DeserializationError == DeserializationError") {
REQUIRE_FALSE(invalidInput == ok);
}
SECTION("DeserializationError != DeserializationError") {
REQUIRE(invalidInput != ok);
}
}
} }