From 95e45dc12c9e313cbb5787978b3e067f581c76c9 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:40:56 +1200 Subject: [PATCH] Allow parse_json to return a boolean result (#6884) * Allow parse_json to return a boolean result * Remove pass variable --- esphome/components/json/json_util.cpp | 17 ++++++++--------- esphome/components/json/json_util.h | 4 ++-- esphome/components/mqtt/mqtt_client.cpp | 5 ++++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/esphome/components/json/json_util.cpp b/esphome/components/json/json_util.cpp index bef494b64d..89ec13fe5b 100644 --- a/esphome/components/json/json_util.cpp +++ b/esphome/components/json/json_util.cpp @@ -62,7 +62,7 @@ std::string build_json(const json_build_t &f) { } } -void parse_json(const std::string &data, const json_parse_t &f) { +bool parse_json(const std::string &data, const json_parse_t &f) { // Here we are allocating 1.5 times the data size, // with the heap size minus 2kb to be safe if less than that // as we can not have a true dynamic sized document. @@ -76,14 +76,13 @@ void parse_json(const std::string &data, const json_parse_t &f) { #elif defined(USE_LIBRETINY) const size_t free_heap = lt_heap_get_free(); #endif - bool pass = false; size_t request_size = std::min(free_heap, (size_t) (data.size() * 1.5)); - do { + while (true) { DynamicJsonDocument json_document(request_size); if (json_document.capacity() == 0) { ESP_LOGE(TAG, "Could not allocate memory for JSON document! Requested %u bytes, free heap: %u", request_size, free_heap); - return; + return false; } DeserializationError err = deserializeJson(json_document, data); json_document.shrinkToFit(); @@ -91,21 +90,21 @@ void parse_json(const std::string &data, const json_parse_t &f) { JsonObject root = json_document.as(); if (err == DeserializationError::Ok) { - pass = true; - f(root); + return f(root); } else if (err == DeserializationError::NoMemory) { if (request_size * 2 >= free_heap) { ESP_LOGE(TAG, "Can not allocate more memory for deserialization. Consider making source string smaller"); - return; + return false; } ESP_LOGV(TAG, "Increasing memory allocation."); request_size *= 2; continue; } else { ESP_LOGE(TAG, "JSON parse error: %s", err.c_str()); - return; + return false; } - } while (!pass); + }; + return false; } } // namespace json diff --git a/esphome/components/json/json_util.h b/esphome/components/json/json_util.h index 2299a4cfed..72d31c8afe 100644 --- a/esphome/components/json/json_util.h +++ b/esphome/components/json/json_util.h @@ -14,7 +14,7 @@ namespace esphome { namespace json { /// Callback function typedef for parsing JsonObjects. -using json_parse_t = std::function; +using json_parse_t = std::function; /// Callback function typedef for building JsonObjects. using json_build_t = std::function; @@ -23,7 +23,7 @@ using json_build_t = std::function; std::string build_json(const json_build_t &f); /// Parse a JSON string and run the provided json parse function if it's valid. -void parse_json(const std::string &data, const json_parse_t &f); +bool parse_json(const std::string &data, const json_parse_t &f); } // namespace json } // namespace esphome diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp index abcbb414d9..d70b9cbd30 100644 --- a/esphome/components/mqtt/mqtt_client.cpp +++ b/esphome/components/mqtt/mqtt_client.cpp @@ -410,7 +410,10 @@ void MQTTClientComponent::subscribe(const std::string &topic, mqtt_callback_t ca void MQTTClientComponent::subscribe_json(const std::string &topic, const mqtt_json_callback_t &callback, uint8_t qos) { auto f = [callback](const std::string &topic, const std::string &payload) { - json::parse_json(payload, [topic, callback](JsonObject root) { callback(topic, root); }); + json::parse_json(payload, [topic, callback](JsonObject root) -> bool { + callback(topic, root); + return true; + }); }; MQTTSubscription subscription{ .topic = topic,