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

Concatenated Names #1904

Closed
Lenbus opened this issue Apr 4, 2023 · 1 comment
Closed

Concatenated Names #1904

Lenbus opened this issue Apr 4, 2023 · 1 comment

Comments

@Lenbus
Copy link

Lenbus commented Apr 4, 2023

I like to utilize ArduinoJSON as a tool for parameter management as I can load params from a file and also can access the parameters via their names e.g. via Serial Communication, e.g. sending "location_lat= 42.0" and my script can adjust the variable calling somthing like doc["location_lat"] = 42.0. That way I can try a whole lot of values for all params on the fly, without re-compiling all the time or using tedious potentiometer reads.

Describe the solution you'd like
I'd really like to take this a step further by also accessing nested objects by a single string-key such as "location.lat = 42.0", which should call doc["location"]["lat"] in the background (maybe there is even a more appropriate delimter than '.'). This should of course work for writing and reading.
I'm pretty sure that this should be quite easy to implement, but I did not manage to implement it myself.

The code necessary for that might look something like this:

// NOTE: This is non-tested Pseudo-Code
String key = "location.lat"
float val = 42.0

String delim = "."
int delim_idx = key.indexOf(delim);

if (delim_idx == -1) { return this[key] }

String key0 = key.substring(0, delim_idx );
String key1 = key.substring(delim_idx + 1);

return this[key0][key1] = val    // Note: if key1 still contains delim-chars, recursion should handle that

Additional context
Moreover: is there any way to implicitly save the var type inside the doc as well?
That way I could call: "Serial << doc["lat"]<< endl;" instead of: "Serial << doc["lat"].as<float>() << endl;"

Regards and let me know, what you think. Keep on the phenomenal work! 😊👍

@bblanchon
Copy link
Owner

Hi,

This request is similar to #821, only simpler.
In your case, the following function should be enough:

JsonVariant resolveJsonPath(JsonVariant variant, const char* path) {
  for (size_t n = 0; path[n]; n++) {
    if (path[n] == '.') {
      variant = variant[JsonString(path, n)];
      path += n + 1;
      n = 0;
    }
  }
  return variant[path];
}

Usage:

// read
double lat = resolveJsonPath(doc, "location.lat");

// write
resolveJsonPath(doc, "location.lat").set(42);

Best regards,
Benoit

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants