From 0cc03dfe327a577d624005381b105f69fa200900 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 25 Sep 2025 16:35:19 +1200 Subject: [PATCH] [json] Parsing json without a lambda (#10838) --- esphome/components/json/json_util.cpp | 19 +++++++++++++------ esphome/components/json/json_util.h | 2 ++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/esphome/components/json/json_util.cpp b/esphome/components/json/json_util.cpp index 51c0fcf9cb..643f23f499 100644 --- a/esphome/components/json/json_util.cpp +++ b/esphome/components/json/json_util.cpp @@ -19,6 +19,15 @@ std::string build_json(const json_build_t &f) { bool parse_json(const std::string &data, const json_parse_t &f) { // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson + JsonDocument doc = parse_json(data); + if (doc.overflowed() || doc.isNull()) + return false; + return f(doc.as()); + // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks) +} + +JsonDocument parse_json(const std::string &data) { + // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson #ifdef USE_PSRAM auto doc_allocator = SpiRamAllocator(); JsonDocument json_document(&doc_allocator); @@ -27,20 +36,18 @@ bool parse_json(const std::string &data, const json_parse_t &f) { #endif if (json_document.overflowed()) { ESP_LOGE(TAG, "Could not allocate memory for JSON document!"); - return false; + return JsonObject(); // return unbound object } DeserializationError err = deserializeJson(json_document, data); - JsonObject root = json_document.as(); - if (err == DeserializationError::Ok) { - return f(root); + return json_document; } else if (err == DeserializationError::NoMemory) { ESP_LOGE(TAG, "Can not allocate more memory for deserialization. Consider making source string smaller"); - return false; + return JsonObject(); // return unbound object } ESP_LOGE(TAG, "Parse error: %s", err.c_str()); - return false; + return JsonObject(); // return unbound object // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks) } diff --git a/esphome/components/json/json_util.h b/esphome/components/json/json_util.h index 69b809ec49..0349833342 100644 --- a/esphome/components/json/json_util.h +++ b/esphome/components/json/json_util.h @@ -49,6 +49,8 @@ std::string build_json(const json_build_t &f); /// Parse a JSON string and run the provided json parse function if it's valid. bool parse_json(const std::string &data, const json_parse_t &f); +/// Parse a JSON string and return the root JsonDocument (or an unbound object on error) +JsonDocument parse_json(const std::string &data); /// Builder class for creating JSON documents without lambdas class JsonBuilder {