|
1 | 1 | // JsonConverters.cpp |
2 | 2 | #include "JsonConverters.hpp" |
3 | 3 | #include "../../json.hpp" |
4 | | -#include <sstream> |
5 | | -#include <iomanip> |
| 4 | +#include <algorithm> |
6 | 5 | #include <cmath> |
| 6 | +#include <iomanip> |
7 | 7 | #include <limits> |
| 8 | +#include <sstream> |
| 9 | +#include <vector> |
8 | 10 |
|
9 | 11 | namespace Modules { |
10 | 12 | namespace JsonConverters { |
@@ -145,51 +147,78 @@ Symbols::ObjectMap convertJsonObjectToMap(const nlohmann::json& json, const std: |
145 | 147 | * @param objMap The ObjectMap to convert |
146 | 148 | * @return nlohmann::json The converted JSON object |
147 | 149 | */ |
| 150 | +// Detect array-shape ObjectMap: every key is "0","1",...,"N-1" with no |
| 151 | +// gaps. Such maps were created from JSON arrays (jsonToValueWithContext) |
| 152 | +// or array literals; round-trip them back as JSON arrays so consumers |
| 153 | +// see the same shape they wrote in. |
| 154 | +static bool isArrayShape(const Symbols::ObjectMap& m) { |
| 155 | + if (m.empty()) return false; |
| 156 | + for (size_t i = 0; i < m.size(); ++i) { |
| 157 | + auto it = m.find(std::to_string(i)); |
| 158 | + if (it == m.end()) return false; |
| 159 | + } |
| 160 | + return true; |
| 161 | +} |
| 162 | + |
148 | 163 | nlohmann::json convertMapToJson(const Symbols::ObjectMap& objMap) { |
149 | | - nlohmann::json result; |
| 164 | + nlohmann::json result = isArrayShape(objMap) ? nlohmann::json::array() |
| 165 | + : nlohmann::json::object(); |
| 166 | + auto put = [&](const std::string& key, nlohmann::json v) { |
| 167 | + if (result.is_array()) result.push_back(std::move(v)); |
| 168 | + else result[key] = std::move(v); |
| 169 | + }; |
| 170 | + |
| 171 | + // For arrays we must iterate in numeric order, not std::map's lex order. |
| 172 | + std::vector<std::string> keys; |
| 173 | + keys.reserve(objMap.size()); |
| 174 | + for (const auto& kv : objMap) keys.push_back(kv.first); |
| 175 | + if (result.is_array()) { |
| 176 | + std::sort(keys.begin(), keys.end(), [](const std::string& a, const std::string& b) { |
| 177 | + return std::stoll(a) < std::stoll(b); |
| 178 | + }); |
| 179 | + } |
150 | 180 |
|
151 | | - for (const auto& kv : objMap) { |
152 | | - const std::string& key = kv.first; |
153 | | - const Symbols::ValuePtr& value = kv.second; |
| 181 | + for (const auto& key : keys) { |
| 182 | + const Symbols::ValuePtr& value = objMap.at(key); |
154 | 183 |
|
155 | 184 | switch (value.getType()) { |
156 | 185 | case Symbols::Variables::Type::NULL_TYPE: |
157 | | - result[key] = nullptr; |
| 186 | + put(key, nullptr); |
158 | 187 | break; |
159 | 188 |
|
160 | 189 | case Symbols::Variables::Type::BOOLEAN: |
161 | | - result[key] = value.get<bool>(); |
| 190 | + put(key, value.get<bool>()); |
162 | 191 | break; |
163 | 192 |
|
164 | 193 | case Symbols::Variables::Type::INTEGER: |
165 | | - result[key] = value.get<int>(); |
| 194 | + put(key, value.get<int>()); |
166 | 195 | break; |
167 | 196 |
|
168 | 197 | case Symbols::Variables::Type::FLOAT: |
169 | | - result[key] = value.get<float>(); |
| 198 | + put(key, value.get<float>()); |
170 | 199 | break; |
171 | 200 |
|
172 | 201 | case Symbols::Variables::Type::DOUBLE: |
173 | | - result[key] = value.get<double>(); |
| 202 | + put(key, value.get<double>()); |
174 | 203 | break; |
175 | 204 |
|
176 | 205 | case Symbols::Variables::Type::STRING: |
177 | | - result[key] = value.get<std::string>(); |
| 206 | + put(key, value.get<std::string>()); |
178 | 207 | break; |
179 | 208 |
|
180 | 209 | case Symbols::Variables::Type::OBJECT: |
181 | 210 | case Symbols::Variables::Type::CLASS: |
182 | | - result[key] = convertMapToJson(value.get<Symbols::ObjectMap>()); |
| 211 | + put(key, convertMapToJson(value.get<Symbols::ObjectMap>())); |
183 | 212 | break; |
184 | 213 |
|
185 | 214 | case Symbols::Variables::Type::ENUM: |
186 | 215 | // Convert enum to string representation |
187 | | - result[key] = value.toString(); |
| 216 | + put(key, value.toString()); |
188 | 217 | break; |
189 | 218 |
|
190 | 219 | default: |
191 | 220 | // Unsupported type, convert to null |
192 | | - result[key] = nullptr; |
| 221 | + put(key, nullptr); |
193 | 222 | break; |
194 | 223 | } |
195 | 224 | } |
|
0 commit comments