Custom converter support for some STL containers such as std::vector, std::array, std::map, etc...
Created by: laferrierepascal
So this might be something that's already available and I just haven't been able to figure out the right combination of syntax to use in order to get it to work, but I've been trying to implement some custom converters for nested custom types, some of which are simply typedefs of STL containers (namely std::array) that contain one of my custom types.
Below is a minimal example of what I'm trying to achieve that results in compilation errors.
constexpr uint8_t POINT_LIST_SIZE = 10;
typedef struct Point
{
Point() : x(.0), y(.0) {};
double x, y;
} Point;
typedef std::array<Point, POINT_LIST_SIZE> PointList;
void convertFromJson(JsonVariantConst src, Point& p)
{
p.x = src["x"];
p.y = src["y"];
}
void convertFromJson(JsonVariantConst src, PointList& list)
{
size_t index = 0;
size_t maximumIndex = list.size();
if (maximumIndex > 0)
{
for (auto p : src.as<JsonArrayConst>())
{
list[index++] = p.as<Point>();
if (index >= maximumIndex) { break;}
}
}
}
Some of the errors that I'm getting are: error: 'bool canConvertFromJson(ArduinoJson::JsonVariantConst, const PointList&)' redeclared as different kind of entity
ArduinoJson/src/ArduinoJson/Variant/ConverterImpl.hpp:32:30: error: 'canConvertFromJson' cannot be used as a function return canConvertFromJson(src, dummy); // Error here? See https://arduinojson.org/v6/unsupported-is/
The reason I believe this is happening is because the template functions only look at the type that's passed in and don't have any mechanism to detect STL containers and redirect to generic algorithms to parse the contents as arrays.
So far I've been able to get the results I need by explicitly defining another struct and making slight adjustments to the conversion function:
typedef struct PointList
{
PointList() {};
std::array<Point, POINT_LIST_SIZE> points;
}
PointList;
void convertFromJson(JsonVariantConst src, PointList& list)
{
size_t index = 0;
size_t maximumIndex = list.points.size();
if (maximumIndex > 0)
{
for (auto p : src.as<JsonArrayConst>())
{
list.points[index++] = p.as<Point>();
if (index >= maximumIndex) { break;}
}
}
}
Ideally I'd like to be able to forego having to redo much of the boilerplate code involved in creating a new class to wrap a container. This was an extremely useful feature that I was able to use in another C++ JSON library (nlohmann::json) which I've had to ditch due to now working on an embedded device. Depending on the size of the project, the number of explicit structure definitions for any custom type within different STL containers can grow rapidly.
Again, I'm not sure if this is currently possible so if there's a way to achieve this I'd be really greatful for some help in getting this working.
Thank you.