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 JsonObject::get<T>(k)` with `JsonVariant JsonObject::get(k)`
* 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)
-----------

View File

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

View File

@ -10,7 +10,15 @@ void testStringification(DeserializationError error, std::string expected) {
}
void testBoolification(DeserializationError error, bool expected) {
// DeserializationError on left-hand side
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) \
@ -38,15 +46,92 @@ TEST_CASE("DeserializationError") {
TEST_BOOLIFICATION(NotSupported, true);
}
SECTION("ostream code") {
SECTION("ostream DeserializationError") {
std::stringstream s;
s << DeserializationError(DeserializationError::InvalidInput);
REQUIRE(s.str() == "InvalidInput");
}
SECTION("ostream code") {
SECTION("ostream DeserializationError::Code") {
std::stringstream s;
s << DeserializationError::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);
}
}
}