/* * Copyright (c) 2025 SimcuTeam. All rights reserved. * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 * JSON 序列化统一工具(对应 C# SimApiUtil.Json)。 */ package simapi.communications import std.collection.* /** * JSON 序列化静态工具类。 * * 说明:序列化核心放在依赖图最底层的 simapi.communications 包, * SimApiUtil.json(simapi.helpers)委托本类实现,避免循环依赖; * 全框架 JSON 输出统一走此处,保证转义与格式一致。 */ public class SimApiJson { private init() {} /** * 对象序列化为 JSON 字符串(统一入口)。 * 支持 String/Int64/Bool/Float64/Array/HashMap,其他类型退化为字符串。 * @param obj 任意对象(None 输出 null)。 */ public static func json(obj: ?Any): String { if (let Some(obj) <- obj) { return jsonValue(obj) } "null" } /** * JSON 字符串转义(统一入口)。 * @param s 原始字符串。 * @return 转义后可直接放入 JSON 字符串字面量的内容。 */ public static func escapeJson(s: String): String { var sb = StringBuilder() for (c in s.runes()) { match (c) { case '"' => sb.append("\\\"") case '\\' => sb.append("\\\\") case '\n' => sb.append("\\n") case '\r' => sb.append("\\r") case '\t' => sb.append("\\t") case _ => sb.append(c) } } sb.toString() } private static func jsonValue(obj: Any): String { if (let s: String <- obj) { return "\"${escapeJson(s)}\"" } if (let i: Int64 <- obj) { return "${i}" } if (let b: Bool <- obj) { return "${b}" } if (let f: Float64 <- obj) { return "${f}" } if (let arr: Array <- obj) { var sb = StringBuilder() sb.append("[") var first = true for (item in arr) { if (!first) { sb.append(",") } sb.append(jsonValue(item)) first = false } sb.append("]") return sb.toString() } if (let map: HashMap <- obj) { var sb = StringBuilder() sb.append("{") var first = true for ((key, value) in map) { if (!first) { sb.append(",") } sb.append("\"${escapeJson(key)}\":${jsonValue(value)}") first = false } sb.append("}") return sb.toString() } // 其他类型退化为字符串 return "\"${escapeJson(describe(obj))}\"" } private static func describe(obj: Any): String { if (let s: ToString <- obj) { return s.toString() } "null" } }