Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comparison operators for custom types #2036

Open
MoonModules opened this issue Jan 15, 2024 · 5 comments
Open

Comparison operators for custom types #2036

MoonModules opened this issue Jan 15, 2024 · 5 comments

Comments

@MoonModules
Copy link

Description

  1. The program uses ArduinoJson 6
  2. The issue happens at compile time
  3. The error is not in the list

See reproduction code below. Using a custom defined struct works for assignments (using Converter<>) as described in https://arduinojson.org/news/2021/05/04/version-6-18-0/

But I cannot get it to work for comparison operators (like var["value"] != value in below example).

I get this error:
.pio/libdeps/esp32dev/ArduinoJson/src/ArduinoJson/Variant/VariantCompare.hpp:203:15: error: 'ArduinoJson::V6214PB2::detail::Comparer<Coordinate, void> comparer' has incomplete type
Comparer comparer(rhs);

Tried to add Comparer like functions but all resulted in compile errors.

Help / code example really appreciated.

Thx
Ewoud

Troubleshooter's report

  1. The program uses ArduinoJson 6
  2. The issue happens at compile time
  3. The error is not in the list

Environment

  • Microcontroller: ESP32
  • Core/Framework: Expressif 3.20014.0
  • IDE: VSCode 1.85 PIO v3.3.2

Reproduction code

This code:

template <typename Type>
JsonObject setValue(const char * id, Type value) {
  JsonObject var = findVar(id);
  if (var["value"].isNull() || var["value"] != value) {
    var["value"] = value;
  }
}

works for:

mdl->setValue<int>("var1", 10);

but not for:

Coordinate xyz;
xyz.x = 1;
xyz.y = 2; 
xyz.z = 3;
mdl->setValue<Coordinate>("var2", xyz, 0);

This code is present:

template <>
struct Converter<Coordinate> {
  static bool toJson(const Coordinate& src, JsonVariant dst) {
    dst["x"] = src.x;
    dst["y"] = src.y;
    dst["z"] = src.z;
    return true;
  }

  static Coordinate fromJson(JsonVariantConst src) {
    return Coordinate{src["x"], src["y"], src["z"]};
  }

  static bool checkJson(JsonVariantConst src) {
    return src["x"].is<int>() && src["y"].is<int>() && src["z"].is<int>();
  }
};


@bblanchon
Copy link
Owner

Hi @MoonModules,

Comparison with custom types is not supported.
As a workaround you can do var["value"].as<Coordinate>() != value.

Best regards,
Benoit

@MoonModules
Copy link
Author

MoonModules commented Jan 17, 2024

Hi Benoit,
Thx for your reply.

Even better (as the function is a template):

JsonObject setValue(const char * id, Type value) {
  JsonObject var = findVar(id);
  if (var["value"].isNull() || var["value"].as<Type>() != value) {
    var["value"] = value;
  }
}

but then != was not defined for Coordinate so I changed the struct:

struct Coordinate {
  uint16_t x;
  uint16_t y;
  uint16_t z;
  bool operator!=(Coordinate par) {
    return x != par.x || y != par.y || z != par.z;
  }
};

And now it's perfect !

One question, is comparison with custom types not supported by design (as it should be done as shown above), or might it be a future enhancement?

Thx again,

Kind regards,

Ewoud from MoonModules

@ewoudwijma
Copy link

ewoudwijma commented Jan 17, 2024

Only thing I am not sure of is if the Type is const char * then the != should be a strcmp ... could that also be overloaded (question to myself 🙂 )

In that case lot less strcmp in code which looks cleaner (but could confuse core char * people 🙂)

@ewoudwijma
Copy link

JsonString ... 🙂

@bblanchon
Copy link
Owner

@MoonModules, I suppose we could make this a feature, but as a wise man once wrote:

Features have a specification cost, a design cost, and a development cost.
There is a testing cost and a reliability cost.
The more features there are, the more likely one will develop problems or will interact badly with another. [...]
Features have a documentation cost.
Every feature adds pages to the manual, increasing training costs.
Features that offer value to a minority of users impose a cost on all users.

It'll convert this issue to a feature request and see if more users are interested.

@bblanchon bblanchon changed the title Compare of JsonVariant with custom Struct not working Comparison operators for custom types Jan 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants