forked from bblanchon/ArduinoJson
Added JsonVariant::operator| to return a default value
This commit is contained in:
263
CHANGELOG.md
263
CHANGELOG.md
@ -3,8 +3,26 @@ ArduinoJson: change log
|
|||||||
|
|
||||||
HEAD
|
HEAD
|
||||||
----
|
----
|
||||||
|
|
||||||
|
* Added `JsonVariant::operator|` to return a default value (see bellow)
|
||||||
* Rewrote example `JsonHttpClient.ino` (issue #600)
|
* Rewrote example `JsonHttpClient.ino` (issue #600)
|
||||||
|
|
||||||
|
> ### How to use the new feature?
|
||||||
|
>
|
||||||
|
> If you have a block like this:
|
||||||
|
>
|
||||||
|
> ```c++
|
||||||
|
> const char* ssid = root["ssid"];
|
||||||
|
> if (!ssid)
|
||||||
|
> ssid = "default ssid";
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> You can simplify like that:
|
||||||
|
>
|
||||||
|
> ```c++
|
||||||
|
> const char* ssid = root["ssid"] | "default ssid";
|
||||||
|
> ```
|
||||||
|
|
||||||
v5.11.2
|
v5.11.2
|
||||||
-------
|
-------
|
||||||
|
|
||||||
@ -46,27 +64,26 @@ v5.10.0
|
|||||||
* Fixed error `IsBaseOf is not a member of ArduinoJson::TypeTraits` (issue #495)
|
* Fixed error `IsBaseOf is not a member of ArduinoJson::TypeTraits` (issue #495)
|
||||||
* Fixed error `forming reference to reference` (issue #495)
|
* Fixed error `forming reference to reference` (issue #495)
|
||||||
|
|
||||||
### BREAKING CHANGES :warning:
|
> ### BREAKING CHANGES :warning:
|
||||||
|
>
|
||||||
| Old syntax | New syntax |
|
> | Old syntax | New syntax |
|
||||||
|:--------------------------------|:--------------------|
|
> |:--------------------------------|:--------------------|
|
||||||
| `double_with_n_digits(3.14, 2)` | `3.14` |
|
> | `double_with_n_digits(3.14, 2)` | `3.14` |
|
||||||
| `float_with_n_digits(3.14, 2)` | `3.14f` |
|
> | `float_with_n_digits(3.14, 2)` | `3.14f` |
|
||||||
| `obj.set("key", 3.14, 2)` | `obj["key"] = 3.14` |
|
> | `obj.set("key", 3.14, 2)` | `obj["key"] = 3.14` |
|
||||||
| `arr.add(3.14, 2)` | `arr.add(3.14)` |
|
> | `arr.add(3.14, 2)` | `arr.add(3.14)` |
|
||||||
|
>
|
||||||
| Input | Old output | New output |
|
> | Input | Old output | New output |
|
||||||
|:----------|:-----------|:-----------|
|
> |:----------|:-----------|:-----------|
|
||||||
| `3.14159` | `3.14` | `3.14159` |
|
> | `3.14159` | `3.14` | `3.14159` |
|
||||||
| `42.0` | `42.00` | `42` |
|
> | `42.0` | `42.00` | `42` |
|
||||||
| `0.0` | `0.00` | `0` |
|
> | `0.0` | `0.00` | `0` |
|
||||||
|
>
|
||||||
| Expression | Old result | New result |
|
> | Expression | Old result | New result |
|
||||||
|:-------------------------------|:-----------|:-----------|
|
> |:-------------------------------|:-----------|:-----------|
|
||||||
| `JsonVariant(42).is<int>()` | `true` | `true` |
|
> | `JsonVariant(42).is<int>()` | `true` | `true` |
|
||||||
| `JsonVariant(42).is<float>()` | `false` | `true` |
|
> | `JsonVariant(42).is<float>()` | `false` | `true` |
|
||||||
| `JsonVariant(42).is<double>()` | `false` | `true` |
|
> | `JsonVariant(42).is<double>()` | `false` | `true` |
|
||||||
|
|
||||||
|
|
||||||
v5.9.0
|
v5.9.0
|
||||||
------
|
------
|
||||||
@ -120,24 +137,23 @@ v5.8.0
|
|||||||
* Added support for `Stream` (issue #300)
|
* Added support for `Stream` (issue #300)
|
||||||
* Reduced memory consumption by not duplicating spaces and comments
|
* Reduced memory consumption by not duplicating spaces and comments
|
||||||
|
|
||||||
### BREAKING CHANGES :warning:
|
> ### BREAKING CHANGES :warning:
|
||||||
|
>
|
||||||
`JsonBuffer::parseObject()` and `JsonBuffer::parseArray()` have been pulled down to the derived classes `DynamicJsonBuffer` and `StaticJsonBufferBase`.
|
> `JsonBuffer::parseObject()` and `JsonBuffer::parseArray()` have been pulled down to the derived classes `DynamicJsonBuffer` and `StaticJsonBufferBase`.
|
||||||
|
>
|
||||||
This means that if you have code like:
|
> This means that if you have code like:
|
||||||
|
>
|
||||||
```c++
|
> ```c++
|
||||||
void myFunction(JsonBuffer& jsonBuffer);
|
> void myFunction(JsonBuffer& jsonBuffer);
|
||||||
```
|
> ```
|
||||||
|
>
|
||||||
you need to replace it with one of the following:
|
> you need to replace it with one of the following:
|
||||||
|
>
|
||||||
```c++
|
> ```c++
|
||||||
void myFunction(DynamicJsonBuffer& jsonBuffer);
|
> void myFunction(DynamicJsonBuffer& jsonBuffer);
|
||||||
void myFunction(StaticJsonBufferBase& jsonBuffer);
|
> void myFunction(StaticJsonBufferBase& jsonBuffer);
|
||||||
template<typename TJsonBuffer> void myFunction(TJsonBuffer& jsonBuffer);
|
> template<typename TJsonBuffer> void myFunction(TJsonBuffer& jsonBuffer);
|
||||||
```
|
> ```
|
||||||
|
|
||||||
|
|
||||||
v5.7.3
|
v5.7.3
|
||||||
------
|
------
|
||||||
@ -170,27 +186,26 @@ v5.7.0
|
|||||||
* Added example `StringExample.ino` to show where `String` can be used
|
* Added example `StringExample.ino` to show where `String` can be used
|
||||||
* Increased default nesting limit to 50 when compiled for a computer (issue #349)
|
* Increased default nesting limit to 50 when compiled for a computer (issue #349)
|
||||||
|
|
||||||
### BREAKING CHANGES :warning:
|
> ### BREAKING CHANGES :warning:
|
||||||
|
>
|
||||||
The non-template functions `JsonObject::get()` and `JsonArray.get()` have been removed. This means that you need to explicitely tell the type you expect in return.
|
> The non-template functions `JsonObject::get()` and `JsonArray.get()` have been removed. This means that you need to explicitely tell the type you expect in return.
|
||||||
|
>
|
||||||
Old code:
|
> Old code:
|
||||||
|
>
|
||||||
```c++
|
> ```c++
|
||||||
#define ARDUINOJSON_USE_ARDUINO_STRING 0
|
> #define ARDUINOJSON_USE_ARDUINO_STRING 0
|
||||||
JsonVariant value1 = myObject.get("myKey");
|
> JsonVariant value1 = myObject.get("myKey");
|
||||||
JsonVariant value2 = myArray.get(0);
|
> JsonVariant value2 = myArray.get(0);
|
||||||
```
|
> ```
|
||||||
|
>
|
||||||
New code:
|
> New code:
|
||||||
|
>
|
||||||
```c++
|
> ```c++
|
||||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
|
> #define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
|
||||||
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
> #define ARDUINOJSON_ENABLE_STD_STRING 1
|
||||||
JsonVariant value1 = myObject.get<JsonVariant>("myKey");
|
> JsonVariant value1 = myObject.get<JsonVariant>("myKey");
|
||||||
JsonVariant value2 = myArray.get<JsonVariant>(0);
|
> JsonVariant value2 = myArray.get<JsonVariant>(0);
|
||||||
```
|
> ```
|
||||||
|
|
||||||
|
|
||||||
v5.6.7
|
v5.6.7
|
||||||
------
|
------
|
||||||
@ -282,8 +297,9 @@ v5.1.0
|
|||||||
* Added support of `long long` (issue #171)
|
* Added support of `long long` (issue #171)
|
||||||
* Moved all build settings to `ArduinoJson/Configuration.hpp`
|
* Moved all build settings to `ArduinoJson/Configuration.hpp`
|
||||||
|
|
||||||
**BREAKING CHANGE**:
|
> ### BREAKING CHANGE :warning:
|
||||||
If you defined `ARDUINOJSON_ENABLE_STD_STREAM`, you now need to define it to `1`.
|
>
|
||||||
|
> If you defined `ARDUINOJSON_ENABLE_STD_STREAM`, you now need to define it to `1`.
|
||||||
|
|
||||||
v5.0.8
|
v5.0.8
|
||||||
------
|
------
|
||||||
@ -297,10 +313,10 @@ v5.0.7
|
|||||||
* Made library easier to use from a CMake project: simply `add_subdirectory(ArduinoJson/src)`
|
* Made library easier to use from a CMake project: simply `add_subdirectory(ArduinoJson/src)`
|
||||||
* Changed `String` to be a `typedef` of `std::string` (issues #142 and #161)
|
* Changed `String` to be a `typedef` of `std::string` (issues #142 and #161)
|
||||||
|
|
||||||
### BREAKING CHANGES :warning:
|
> ### BREAKING CHANGES :warning:
|
||||||
|
>
|
||||||
- `JsonVariant(true).as<String>()` now returns `"true"` instead of `"1"`
|
> - `JsonVariant(true).as<String>()` now returns `"true"` instead of `"1"`
|
||||||
- `JsonVariant(false).as<String>()` now returns `"false"` instead of `"0"`
|
> - `JsonVariant(false).as<String>()` now returns `"false"` instead of `"0"`
|
||||||
|
|
||||||
v5.0.6
|
v5.0.6
|
||||||
------
|
------
|
||||||
@ -354,11 +370,11 @@ v5.0.0
|
|||||||
* Redesigned `JsonVariant` to leverage converting constructors instead of assignment operators (issue #66)
|
* Redesigned `JsonVariant` to leverage converting constructors instead of assignment operators (issue #66)
|
||||||
* Switched to new the library layout (requires Arduino 1.0.6 or above)
|
* Switched to new the library layout (requires Arduino 1.0.6 or above)
|
||||||
|
|
||||||
### BREAKING CHANGES :warning:
|
> ### BREAKING CHANGES :warning:
|
||||||
|
>
|
||||||
- `JsonObject::add()` was renamed to `set()`
|
> - `JsonObject::add()` was renamed to `set()`
|
||||||
- `JsonArray::at()` and `JsonObject::at()` were renamed to `get()`
|
> - `JsonArray::at()` and `JsonObject::at()` were renamed to `get()`
|
||||||
- Number of digits of floating point value are now set with `double_with_n_digits()`
|
> - Number of digits of floating point value are now set with `double_with_n_digits()`
|
||||||
|
|
||||||
**Personal note about the `String` class**:
|
**Personal note about the `String` class**:
|
||||||
Support of the `String` class has been added to the library because many people use it in their programs.
|
Support of the `String` class has been added to the library because many people use it in their programs.
|
||||||
@ -411,106 +427,7 @@ v4.0
|
|||||||
* Unified parser and generator API (issue #23)
|
* Unified parser and generator API (issue #23)
|
||||||
* Updated library layout, now requires Arduino 1.0.6 or newer
|
* Updated library layout, now requires Arduino 1.0.6 or newer
|
||||||
|
|
||||||
**BREAKING CHANGE**: API changed significantly, see [Migrating code to the new API](https://github.com/bblanchon/ArduinoJson/wiki/Migrating-code-to-the-new-API).
|
> ### BREAKING CHANGES :warning:
|
||||||
|
>
|
||||||
|
> API changed significantly since v3, see [Migrating code to the new API](http://arduinojson.org/doc/migration/).
|
||||||
|
|
||||||
|
|
||||||
v3.4
|
|
||||||
----
|
|
||||||
|
|
||||||
* Fixed escaped char parsing (issue #16)
|
|
||||||
|
|
||||||
|
|
||||||
v3.3
|
|
||||||
----
|
|
||||||
|
|
||||||
* Added indented output for the JSON generator (issue #11), see example bellow.
|
|
||||||
* Added `IndentedPrint`, a decorator for `Print` to allow indented output
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
JsonOject<2> json;
|
|
||||||
json["key"] = "value";
|
|
||||||
json.prettyPrintTo(Serial);
|
|
||||||
|
|
||||||
v3.2
|
|
||||||
----
|
|
||||||
|
|
||||||
* Fixed a bug when adding nested object in `JsonArray` (bug introduced in v3.1).
|
|
||||||
|
|
||||||
v3.1
|
|
||||||
----
|
|
||||||
|
|
||||||
* Calling `Generator::JsonObject::add()` twice with the same `key` now replaces the `value`
|
|
||||||
* Added `Generator::JsonObject::operator[]`, see bellow the new API
|
|
||||||
* Added `Generator::JsonObject::remove()` (issue #9)
|
|
||||||
|
|
||||||
Old generator API:
|
|
||||||
|
|
||||||
JsonObject<3> root;
|
|
||||||
root.add("sensor", "gps");
|
|
||||||
root.add("time", 1351824120);
|
|
||||||
root.add("data", array);
|
|
||||||
|
|
||||||
New generator API:
|
|
||||||
|
|
||||||
JsonObject<3> root;
|
|
||||||
root["sensor"] = "gps";
|
|
||||||
root["time"] = 1351824120;
|
|
||||||
root["data"] = array;
|
|
||||||
|
|
||||||
v3.0
|
|
||||||
----
|
|
||||||
|
|
||||||
* New parser API, see bellow
|
|
||||||
* Renamed `JsonHashTable` into `JsonObject`
|
|
||||||
* Added iterators for `JsonArray` and `JsonObject` (issue #4)
|
|
||||||
|
|
||||||
Old parser API:
|
|
||||||
|
|
||||||
JsonHashTable root = parser.parseHashTable(json);
|
|
||||||
|
|
||||||
char* sensor = root.getString("sensor");
|
|
||||||
long time = root.getLong("time");
|
|
||||||
double latitude = root.getArray("data").getDouble(0);
|
|
||||||
double longitude = root.getArray("data").getDouble(1);
|
|
||||||
|
|
||||||
New parser API:
|
|
||||||
|
|
||||||
JsonObject root = parser.parse(json);
|
|
||||||
|
|
||||||
char* sensor = root["sensor"];
|
|
||||||
long time = root["time"];
|
|
||||||
double latitude = root["data"][0];
|
|
||||||
double longitude = root["data"][1];
|
|
||||||
|
|
||||||
v2.1
|
|
||||||
----
|
|
||||||
|
|
||||||
* Fixed case `#include "jsmn.cpp"` which caused an error in Linux (issue #6)
|
|
||||||
* Fixed a buffer overrun in JSON Parser (issue #5)
|
|
||||||
|
|
||||||
v2.0
|
|
||||||
----
|
|
||||||
|
|
||||||
* Added JSON encoding (issue #2)
|
|
||||||
* Renamed the library `ArduinoJsonParser` becomes `ArduinoJson`
|
|
||||||
|
|
||||||
**Breaking change**: you need to add the following line at the top of your program.
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Parser;
|
|
||||||
|
|
||||||
v1.2
|
|
||||||
----
|
|
||||||
|
|
||||||
* Fixed error in JSON parser example (issue #1)
|
|
||||||
|
|
||||||
v1.1
|
|
||||||
----
|
|
||||||
|
|
||||||
* Example: changed `char* json` into `char[] json` so that the bytes are not write protected
|
|
||||||
* Fixed parsing bug when the JSON contains multi-dimensional arrays
|
|
||||||
|
|
||||||
v1.0
|
|
||||||
----
|
|
||||||
|
|
||||||
Initial release
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "JsonVariantCasts.hpp"
|
#include "JsonVariantCasts.hpp"
|
||||||
#include "JsonVariantComparisons.hpp"
|
#include "JsonVariantComparisons.hpp"
|
||||||
|
#include "JsonVariantOr.hpp"
|
||||||
#include "JsonVariantSubscripts.hpp"
|
#include "JsonVariantSubscripts.hpp"
|
||||||
#include "Serialization/JsonPrintable.hpp"
|
#include "Serialization/JsonPrintable.hpp"
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ template <typename TImpl>
|
|||||||
class JsonVariantBase : public Internals::JsonPrintable<TImpl>,
|
class JsonVariantBase : public Internals::JsonPrintable<TImpl>,
|
||||||
public JsonVariantCasts<TImpl>,
|
public JsonVariantCasts<TImpl>,
|
||||||
public JsonVariantComparisons<TImpl>,
|
public JsonVariantComparisons<TImpl>,
|
||||||
|
public JsonVariantOr<TImpl>,
|
||||||
public JsonVariantSubscripts<TImpl>,
|
public JsonVariantSubscripts<TImpl>,
|
||||||
public TypeTraits::JsonVariantTag {};
|
public TypeTraits::JsonVariantTag {};
|
||||||
}
|
}
|
||||||
|
36
src/ArduinoJson/JsonVariantOr.hpp
Normal file
36
src/ArduinoJson/JsonVariantOr.hpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2017
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Data/JsonVariantAs.hpp"
|
||||||
|
#include "Polyfills/attributes.hpp"
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
|
||||||
|
template <typename TImpl>
|
||||||
|
class JsonVariantOr {
|
||||||
|
public:
|
||||||
|
// Returns the default value if the JsonVariant is undefined of incompatible
|
||||||
|
template <typename T>
|
||||||
|
T operator|(const T &defaultValue) const {
|
||||||
|
if (impl()->template is<T>())
|
||||||
|
return impl()->template as<T>();
|
||||||
|
else
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the default value if the JsonVariant is undefined of incompatible
|
||||||
|
// Special case for string: null is treated as undefined
|
||||||
|
const char *operator|(const char *defaultValue) const {
|
||||||
|
const char *value = impl()->template as<const char *>();
|
||||||
|
return value ? value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const TImpl *impl() const {
|
||||||
|
return static_cast<const TImpl *>(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -7,6 +7,7 @@ add_executable(JsonVariantTests
|
|||||||
compare.cpp
|
compare.cpp
|
||||||
copy.cpp
|
copy.cpp
|
||||||
is.cpp
|
is.cpp
|
||||||
|
or.cpp
|
||||||
printTo.cpp
|
printTo.cpp
|
||||||
set_get.cpp
|
set_get.cpp
|
||||||
subscript.cpp
|
subscript.cpp
|
||||||
|
77
test/JsonVariant/or.cpp
Normal file
77
test/JsonVariant/or.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2017
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
static const JsonVariant undefined;
|
||||||
|
static const JsonVariant null = static_cast<const char*>(0);
|
||||||
|
|
||||||
|
TEST_CASE("JsonVariant::operator|()") {
|
||||||
|
SECTION("undefined | const char*") {
|
||||||
|
std::string result = undefined | "default";
|
||||||
|
REQUIRE(result == "default");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("undefined | int") {
|
||||||
|
int result = undefined | 42;
|
||||||
|
REQUIRE(result == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("undefined | bool") {
|
||||||
|
bool result = undefined | true;
|
||||||
|
REQUIRE(result == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("null | const char*") {
|
||||||
|
std::string result = null | "default";
|
||||||
|
REQUIRE(result == "default");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("null | int") {
|
||||||
|
int result = null | 42;
|
||||||
|
REQUIRE(result == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("null | bool") {
|
||||||
|
bool result = null | true;
|
||||||
|
REQUIRE(result == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("int | const char*") {
|
||||||
|
JsonVariant variant = 42;
|
||||||
|
std::string result = variant | "default";
|
||||||
|
REQUIRE(result == "default");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("int | int") {
|
||||||
|
JsonVariant variant = 0;
|
||||||
|
int result = variant | 666;
|
||||||
|
REQUIRE(result == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("bool | bool") {
|
||||||
|
JsonVariant variant = false;
|
||||||
|
bool result = variant | true;
|
||||||
|
REQUIRE(result == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("int | bool") {
|
||||||
|
JsonVariant variant = 0;
|
||||||
|
bool result = variant | true;
|
||||||
|
REQUIRE(result == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("const char* | const char*") {
|
||||||
|
JsonVariant variant = "not default";
|
||||||
|
std::string result = variant | "default";
|
||||||
|
REQUIRE(result == "not default");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("const char* | int") {
|
||||||
|
JsonVariant variant = "not default";
|
||||||
|
int result = variant | 42;
|
||||||
|
REQUIRE(result == 42);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user