Compare commits
2
Commits
ab1e04787e
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9539e34bee | ||
|
|
46bd710128 |
@@ -1,2 +1,5 @@
|
|||||||
target/
|
target/
|
||||||
*.cj.macrocall
|
*.cj.macrocall
|
||||||
|
# 宏编译产物(构建时自动生成,不入库)
|
||||||
|
src/macros/*.cjo
|
||||||
|
src/macros/*.dll
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
name = "serialization"
|
name = "serialization"
|
||||||
organization = "simcu"
|
organization = "simcu"
|
||||||
description = "SimApi 全反射 JSON 序列化库(对齐 .NET JsonSerializer.Serialize/Deserialize + SerializerPropertyName/SerializerIgnore 特性)"
|
description = "SimApi 全反射 JSON 序列化库(对齐 .NET JsonSerializer.Serialize/Deserialize + SerializerPropertyName/SerializerIgnore 特性)"
|
||||||
version = "1.0.3"
|
version = "1.1.0"
|
||||||
target-dir = ""
|
target-dir = ""
|
||||||
output-type = "static"
|
output-type = "static"
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ package simcu::serialization.json
|
|||||||
import std.collection.*
|
import std.collection.*
|
||||||
import std.convert.*
|
import std.convert.*
|
||||||
import std.reflect.*
|
import std.reflect.*
|
||||||
|
import std.time.*
|
||||||
import stdx.encoding.json.*
|
import stdx.encoding.json.*
|
||||||
import simcu::serialization.common.ReflectionCache
|
import simcu::serialization.common.ReflectionCache
|
||||||
import simcu::serialization.common.FieldMetadata
|
import simcu::serialization.common.FieldMetadata
|
||||||
@@ -62,6 +63,7 @@ public class JsonReader {
|
|||||||
case "Float64" => return readFloat64(value)
|
case "Float64" => return readFloat64(value)
|
||||||
case "Float32" => return Float32(readFloat64(value))
|
case "Float32" => return Float32(readFloat64(value))
|
||||||
case "Rune" => return readChar(value)
|
case "Rune" => return readChar(value)
|
||||||
|
case "DateTime" | "std.time.DateTime" => return readDateTime(value)
|
||||||
case _ => ()
|
case _ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,6 +300,15 @@ public class JsonReader {
|
|||||||
throw Exception("JsonSerializer: 无法转换为 Char")
|
throw Exception("JsonSerializer: 无法转换为 Char")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static func readDateTime(v: JsonValue): DateTime {
|
||||||
|
let s = readString(v)
|
||||||
|
try {
|
||||||
|
return DateTime.parse(s, "yyyy-MM-dd HH:mm:ss")
|
||||||
|
} catch (_: Exception) {
|
||||||
|
throw Exception("JsonSerializer: 无法转换为 DateTime: ${s}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 生成某类型的占位默认值(用于构造 Option<X> 的 None:None 的参数槽类型是 X)。
|
/// 生成某类型的占位默认值(用于构造 Option<X> 的 None:None 的参数槽类型是 X)。
|
||||||
private static func defaultValueFor(typeName: String): Any {
|
private static func defaultValueFor(typeName: String): Any {
|
||||||
match (typeName) {
|
match (typeName) {
|
||||||
@@ -314,6 +325,7 @@ public class JsonReader {
|
|||||||
case "Float64" => return Float64(0.0)
|
case "Float64" => return Float64(0.0)
|
||||||
case "Float32" => return Float32(0.0)
|
case "Float32" => return Float32(0.0)
|
||||||
case "Rune" => return Rune(0)
|
case "Rune" => return Rune(0)
|
||||||
|
case "DateTime" | "std.time.DateTime" => return DateTime.parse("1970-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss")
|
||||||
case _ => ()
|
case _ => ()
|
||||||
}
|
}
|
||||||
// 集合/对象/枚举:反射无参构造;失败则抛异常
|
// 集合/对象/枚举:反射无参构造;失败则抛异常
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ package simcu::serialization.json
|
|||||||
|
|
||||||
import std.collection.*
|
import std.collection.*
|
||||||
import std.reflect.*
|
import std.reflect.*
|
||||||
|
import std.time.*
|
||||||
import stdx.encoding.json.*
|
import stdx.encoding.json.*
|
||||||
import simcu::serialization.common.ReflectionCache
|
import simcu::serialization.common.ReflectionCache
|
||||||
import simcu::serialization.common.FieldMetadata
|
import simcu::serialization.common.FieldMetadata
|
||||||
@@ -42,6 +43,7 @@ public class JsonWriter {
|
|||||||
if (let u64: UInt64 <- value) { return JsonInt(Int64(u64)) }
|
if (let u64: UInt64 <- value) { return JsonInt(Int64(u64)) }
|
||||||
if (let f32: Float32 <- value) { return JsonFloat(Float64(f32)) }
|
if (let f32: Float32 <- value) { return JsonFloat(Float64(f32)) }
|
||||||
if (let c: Rune <- value) { return JsonString("${c}") }
|
if (let c: Rune <- value) { return JsonString("${c}") }
|
||||||
|
if (let dt: DateTime <- value) { return JsonString(dt.format("yyyy-MM-dd HH:mm:ss")) }
|
||||||
|
|
||||||
let typeName = TypeInfo.of(value).toString()
|
let typeName = TypeInfo.of(value).toString()
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
package simcu::serialization.tests
|
package simcu::serialization.tests
|
||||||
|
|
||||||
import std.collection.*
|
import std.collection.*
|
||||||
|
import std.time.*
|
||||||
import std.unittest.*
|
import std.unittest.*
|
||||||
import std.unittest.testmacro.*
|
import std.unittest.testmacro.*
|
||||||
import simcu::serialization.*
|
import simcu::serialization.*
|
||||||
@@ -55,6 +56,13 @@ class User <: BaseUser {
|
|||||||
public var temp: String = "secret" // 无下划线 + 忽略
|
public var temp: String = "secret" // 无下划线 + 忽略
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DateTime 字段测试实体
|
||||||
|
class Event {
|
||||||
|
public var _name: String = ""
|
||||||
|
public var _time: DateTime = DateTime.parse("1970-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss")
|
||||||
|
public var _optTime: ?DateTime = None
|
||||||
|
}
|
||||||
|
|
||||||
// 多层继承:爷(标宏)→ 父(不标宏)→ 子
|
// 多层继承:爷(标宏)→ 父(不标宏)→ 子
|
||||||
@SerializerParent
|
@SerializerParent
|
||||||
open class GrandParent {
|
open class GrandParent {
|
||||||
@@ -304,6 +312,35 @@ public class JsonSerializerTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// DateTime:输出 yyyy-MM-dd HH:mm:ss 字符串并可反序列化回
|
||||||
|
@TestCase
|
||||||
|
public func dateTimeRoundTrip(): Unit {
|
||||||
|
let e = Event()
|
||||||
|
e._name = "login"
|
||||||
|
e._time = DateTime.parse("2026-08-21 02:27:48", "yyyy-MM-dd HH:mm:ss")
|
||||||
|
e._optTime = Some(DateTime.parse("2026-01-02 03:04:05", "yyyy-MM-dd HH:mm:ss"))
|
||||||
|
let json = JsonSerializer.Serialize(e)
|
||||||
|
@Expect(json.contains("\"_time\": \"2026-08-21 02:27:48\""), true)
|
||||||
|
@Expect(json.contains("\"_optTime\": \"2026-01-02 03:04:05\""), true)
|
||||||
|
let back = JsonSerializer.Deserialize<Event>(json)
|
||||||
|
@Expect(back._time.format("yyyy-MM-dd HH:mm:ss"), "2026-08-21 02:27:48")
|
||||||
|
let optVal: ?DateTime = back._optTime
|
||||||
|
@Expect(optVal.isSome(), true)
|
||||||
|
if (let Some(dt) <- optVal) {
|
||||||
|
@Expect(dt.format("yyyy-MM-dd HH:mm:ss"), "2026-01-02 03:04:05")
|
||||||
|
}
|
||||||
|
// 顶层 DateTime 直接序列化
|
||||||
|
@Expect(JsonSerializer.Serialize(back._time), "\"2026-08-21 02:27:48\"")
|
||||||
|
// Option<DateTime> None → null
|
||||||
|
let e2 = Event()
|
||||||
|
e2._name = "n"
|
||||||
|
e2._time = DateTime.parse("2026-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss")
|
||||||
|
let json2 = JsonSerializer.Serialize(e2)
|
||||||
|
@Expect(json2.contains("\"_optTime\": null"), true)
|
||||||
|
let back2 = JsonSerializer.Deserialize<Event>(json2)
|
||||||
|
@Expect(back2._optTime.isNone(), true)
|
||||||
|
}
|
||||||
|
|
||||||
/// 宽松类型转换:JSON 数字 ↔ 字符串字段互转
|
/// 宽松类型转换:JSON 数字 ↔ 字符串字段互转
|
||||||
@TestCase
|
@TestCase
|
||||||
public func looseConversion(): Unit {
|
public func looseConversion(): Unit {
|
||||||
|
|||||||
Reference in New Issue
Block a user