/* * Copyright (c) 2025 SimcuTeam. All rights reserved. * JsonWriter:对象 → JsonValue(全反射)。 * * 集合处理:仓颉泛型是不变的(Array 不能 cast 为 Array), * 因此通过反射调用 iterator()/hasNext()/next() 与 keys()/get() 迭代元素。 */ package simapi_serialization.json import std.collection.* import std.reflect.* import stdx.encoding.json.* /** * 对象 → JsonValue 写入器。 */ public class JsonWriter { private init() {} public static func write(obj: Any, options: JsonOption): JsonValue { writeValue(obj, options, 0) } private static func writeValue(value: Any, options: JsonOption, depth: Int64): JsonValue { if (depth > options.maxDepth) { throw Exception("JsonSerializer: 超过最大递归深度 ${options.maxDepth}") } // 基本类型(快路径) if (let s: String <- value) { return JsonString(s) } if (let b: Bool <- value) { return JsonBool(b) } if (let i: Int64 <- value) { return JsonInt(i) } if (let f: Float64 <- value) { return JsonFloat(f) } if (let i32: Int32 <- value) { return JsonInt(Int64(i32)) } if (let i16: Int16 <- value) { return JsonInt(Int64(i16)) } if (let i8: Int8 <- value) { return JsonInt(Int64(i8)) } if (let u8: UInt8 <- value) { return JsonInt(Int64(u8)) } if (let u16: UInt16 <- value) { return JsonInt(Int64(u16)) } if (let u32: UInt32 <- value) { return JsonInt(Int64(u32)) } if (let u64: UInt64 <- value) { return JsonInt(Int64(u64)) } if (let f32: Float32 <- value) { return JsonFloat(Float64(f32)) } if (let c: Rune <- value) { return JsonString("${c}") } let typeName = TypeInfo.of(value).toString() // Option 值(Some(x) / None):仓颉 Option 是泛型枚举,用 destruct 取关联值 if (typeName.startsWith("Option<")) { if (let Some(inner) <- unwrapOptionValue(value)) { return writeValue(inner, options, depth + 1) } return JsonNull() } // 集合:Array / ArrayList / HashSet(统一反射迭代) if (typeName.startsWith("Array<") || typeName.startsWith("std.collection.ArrayList<") || typeName.startsWith("std.collection.HashSet<")) { return writeCollection(value, options, depth) } // HashMap if (typeName.startsWith("std.collection.HashMap<")) { return writeHashMap(value, options, depth) } let ti2 = TypeInfo.of(value) // 枚举:destruct 取构造器名 if (let et: EnumTypeInfo <- ti2) { let (ctor, _) = et.destruct(value) return JsonString(ctor.name) } // 对象:反射字段 if (let ct: ClassTypeInfo <- ti2) { return writeObject(value, ct, options, depth) } throw Exception("JsonSerializer: 不支持的类型 ${typeName}") } private static func writeCollection(value: Any, options: JsonOption, depth: Int64): JsonValue { let arr = JsonArray() forEachElement(value) { elem => arr.add(writeValue(elem, options, depth + 1)) } arr } private static func writeHashMap(value: Any, options: JsonOption, depth: Int64): JsonValue { let obj = JsonObject() let ti = TypeInfo.of(value) let typeName = ti.toString() let args = extractTypeArgs(typeName) let keyType = if (args.size > 0) { TypeInfo.get(args[0]) } else { TypeInfo.of() } let getFunc = ti.getInstanceFunction("get", [keyType]) let keys = ti.getInstanceFunction("keys", []).apply(value, []) forEachElement(keys) { k => let v = getFunc.apply(value, [k]) obj.put(toKeyString(k), writeValue(v, options, depth + 1)) } obj } private static func writeObject(value: Any, ct: ClassTypeInfo, options: JsonOption, depth: Int64): JsonValue { let obj = JsonObject() let fields = ReflectionCache.getFields(ct, options) for (f in fields) { if (f.ignore) { continue } let raw = f.variable.getOrThrow().getValue(value) if (options.ignoreNull && isNoneValue(raw)) { continue } obj.put(f.jsonName, writeValue(raw, options, depth + 1)) } obj } /// 反射迭代集合:优先 toArray 转数组再 get(index);无 toArray(如 Array)直接用原集合 private static func forEachElement(collection: Any, action: (Any) -> Unit): Unit { let ti = TypeInfo.of(collection) var arr: Any = collection try { arr = ti.getInstanceFunction("toArray", []).apply(collection, []) } catch (_: Exception) { // 无 toArray(如 Array):直接用原集合 get(i) } let arrTi = TypeInfo.of(arr) // 仓颉集合 get(index) 返回 Option:Some(元素) / None(越界结束) let getFunc = arrTi.getInstanceFunction("get", [TypeInfo.of()]) var i: Int64 = 0 var guard: Int64 = 0 while (true) { guard += 1 if (guard > 1000000) { throw Exception("JsonSerializer: 集合迭代超限 type=${TypeInfo.of(arr)}") } var elem: ?Any = None try { elem = Some(getFunc.apply(arr, [i])) } catch (_: Exception) { break } if (let Some(v) <- unwrapOptionValue(elem.getOrThrow())) { action(v) } else { break } i += 1 } } /// 判断 Any 值是否为 None(Option 枚举的 None 构造器;非 Option 值返回 false) private static func isNoneValue(v: Any): Bool { if (let et: EnumTypeInfo <- TypeInfo.of(v)) { let (ctor, _) = et.destruct(v) return ctor.name == "None" } false } /// 若值为 Option 的 Some(x) 返回 Some(x);None 或非 Option 返回 None private static func unwrapOptionValue(v: Any): ?Any { if (let et: EnumTypeInfo <- TypeInfo.of(v)) { let (ctor, values) = et.destruct(v) if (ctor.name == "Some" && values.size > 0) { return Some(values[0]) } } None } private static func toKeyString(k: Any): String { if (let s: String <- k) { return s } if (let s: ToString <- k) { return s.toString() } TypeInfo.of(k).toString() } /// 从 "Array" / "std.collection.HashMap" / "Option" 提取类型参数 public static func extractTypeArgs(typeName: String): ArrayList { var args = ArrayList() match (typeName.indexOf("<")) { case None => return args case Some(i) => var depth: Int64 = 0 var start = i + 1 var j = i + 1 while (j < typeName.size) { let b = typeName[j] if (b == 0x3Cu8) { // '<' depth += 1 } else if (b == 0x3Eu8) { // '>' if (depth == 0) { args.add(typeName[start..j]) return args } depth -= 1 } else if (b == 0x2Cu8) { // ',' if (depth == 0) { args.add(typeName[start..j]) start = j + 1 } } j += 1 } } args } }