101 lines
2.9 KiB
Plaintext
101 lines
2.9 KiB
Plaintext
/*
|
||
* 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<Any> <- 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<String, Any> <- 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"
|
||
}
|
||
}
|