Minimal JSON map parser (no external deps for build.rs usage).
(json: &str)
| 300 | |
| 301 | /// Minimal JSON map parser (no external deps for build.rs usage). |
| 302 | fn parse_simple_json_map(json: &str) -> HashMap<String, String> { |
| 303 | let mut map = HashMap::default(); |
| 304 | let trimmed = json.trim(); |
| 305 | if !trimmed.starts_with('{') || !trimmed.ends_with('}') { |
| 306 | return map; |
| 307 | } |
| 308 | let inner = &trimmed[1..trimmed.len() - 1]; |
| 309 | // Split by commas that are outside quotes |
| 310 | let mut key = String::new(); |
| 311 | let mut value = String::new(); |
| 312 | let mut in_key = false; |
| 313 | let mut in_value = false; |
| 314 | let mut in_string = false; |
| 315 | let mut escape_next = false; |
| 316 | let mut after_colon = false; |
| 317 | |
| 318 | for ch in inner.chars() { |
| 319 | if escape_next { |
| 320 | if in_key { |
| 321 | key.push(ch); |
| 322 | } else if in_value { |
| 323 | value.push(ch); |
| 324 | } |
| 325 | escape_next = false; |
| 326 | continue; |
| 327 | } |
| 328 | if ch == '\\' && in_string { |
| 329 | escape_next = true; |
| 330 | if in_key { |
| 331 | key.push(ch); |
| 332 | } else if in_value { |
| 333 | value.push(ch); |
| 334 | } |
| 335 | continue; |
| 336 | } |
| 337 | if ch == '"' { |
| 338 | if !in_string { |
| 339 | in_string = true; |
| 340 | if !after_colon { |
| 341 | in_key = true; |
| 342 | in_value = false; |
| 343 | } else { |
| 344 | in_value = true; |
| 345 | in_key = false; |
| 346 | } |
| 347 | } else { |
| 348 | in_string = false; |
| 349 | if in_value { |
| 350 | map.insert(key.clone(), value.clone()); |
| 351 | key.clear(); |
| 352 | value.clear(); |
| 353 | in_key = false; |
| 354 | in_value = false; |
| 355 | after_colon = false; |
| 356 | } |
| 357 | if in_key { |
| 358 | in_key = false; |
| 359 | } |