| 184 | } |
| 185 | |
| 186 | bool ScreenMap::ParseJson(const char *jsonStrScreenMap, |
| 187 | fl::flat_map<string, ScreenMap> *segmentMaps, string *err) { |
| 188 | |
| 189 | #if FASTLED_NO_JSON |
| 190 | FL_UNUSED(jsonStrScreenMap); |
| 191 | FL_UNUSED(segmentMaps); |
| 192 | FL_UNUSED(err); |
| 193 | FL_WARN("ScreenMap::ParseJson called with FASTLED_NO_JSON"); |
| 194 | if (err) { |
| 195 | *err = "JSON is not supported in this build"; |
| 196 | } |
| 197 | return false; |
| 198 | #else |
| 199 | //FL_WARN_SCREENMAP("ParseJson called with JSON: " << jsonStrScreenMap); |
| 200 | |
| 201 | string _err; |
| 202 | if (!err) { |
| 203 | err = &_err; |
| 204 | } |
| 205 | |
| 206 | auto jsonDoc = fl::json::parse(jsonStrScreenMap); |
| 207 | if (!jsonDoc.has_value()) { |
| 208 | *err = "Failed to parse JSON"; |
| 209 | FL_WARN("Failed to parse JSON"); |
| 210 | return false; |
| 211 | } |
| 212 | |
| 213 | if (!jsonDoc.is_object()) { |
| 214 | *err = "JSON root is not an object"; |
| 215 | FL_WARN("JSON root is not an object"); |
| 216 | return false; |
| 217 | } |
| 218 | |
| 219 | // ── v2 dispatch ────────────────────────────────────────────────────── |
| 220 | // v2 if: explicit "version": 2 OR has top-level "segments" array. |
| 221 | // v1 if: explicit "version": 1 OR has top-level "map" object. |
| 222 | bool explicitV2 = false; |
| 223 | bool explicitV1 = false; |
| 224 | if (jsonDoc.contains("version") && jsonDoc["version"].has_value()) { |
| 225 | auto versionOpt = jsonDoc["version"].as_int(); |
| 226 | if (versionOpt) { |
| 227 | int v = static_cast<int>(*versionOpt); |
| 228 | if (v == 2) explicitV2 = true; |
| 229 | else if (v == 1) explicitV1 = true; |
| 230 | } |
| 231 | } |
| 232 | bool hasSegments = jsonDoc.contains("segments") && jsonDoc["segments"].has_value() |
| 233 | && jsonDoc["segments"].is_array(); |
| 234 | bool hasMap = jsonDoc.contains("map") && jsonDoc["map"].has_value() |
| 235 | && jsonDoc["map"].is_object(); |
| 236 | |
| 237 | if (explicitV2 || (!explicitV1 && hasSegments && !hasMap)) { |
| 238 | return parseV2SegmentArray(jsonDoc["segments"], segmentMaps, err); |
| 239 | } |
| 240 | |
| 241 | // Fall through to v1 path. |
| 242 | // Check if "map" key exists and is an object |
| 243 | if (!jsonDoc.contains("map")) { |
nothing calls this directly
no test coverage detected