Compare commits
2
Commits
ab1e04787e
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9539e34bee | ||
|
|
46bd710128 |
@@ -1,2 +1,5 @@
|
||||
target/
|
||||
*.cj.macrocall
|
||||
# 宏编译产物(构建时自动生成,不入库)
|
||||
src/macros/*.cjo
|
||||
src/macros/*.dll
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
name = "serialization"
|
||||
organization = "simcu"
|
||||
description = "SimApi 全反射 JSON 序列化库(对齐 .NET JsonSerializer.Serialize/Deserialize + SerializerPropertyName/SerializerIgnore 特性)"
|
||||
version = "1.0.3"
|
||||
version = "1.1.0"
|
||||
target-dir = ""
|
||||
output-type = "static"
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ package simcu::serialization.json
|
||||
import std.collection.*
|
||||
import std.convert.*
|
||||
import std.reflect.*
|
||||
import std.time.*
|
||||
import stdx.encoding.json.*
|
||||
import simcu::serialization.common.ReflectionCache
|
||||
import simcu::serialization.common.FieldMetadata
|
||||
@@ -62,6 +63,7 @@ public class JsonReader {
|
||||
case "Float64" => return readFloat64(value)
|
||||
case "Float32" => return Float32(readFloat64(value))
|
||||
case "Rune" => return readChar(value)
|
||||
case "DateTime" | "std.time.DateTime" => return readDateTime(value)
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
@@ -298,6 +300,15 @@ public class JsonReader {
|
||||
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)。
|
||||
private static func defaultValueFor(typeName: String): Any {
|
||||
match (typeName) {
|
||||
@@ -314,6 +325,7 @@ public class JsonReader {
|
||||
case "Float64" => return Float64(0.0)
|
||||
case "Float32" => return Float32(0.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 _ => ()
|
||||
}
|
||||
// 集合/对象/枚举:反射无参构造;失败则抛异常
|
||||
|
||||
@@ -10,6 +10,7 @@ package simcu::serialization.json
|
||||
|
||||
import std.collection.*
|
||||
import std.reflect.*
|
||||
import std.time.*
|
||||
import stdx.encoding.json.*
|
||||
import simcu::serialization.common.ReflectionCache
|
||||
import simcu::serialization.common.FieldMetadata
|
||||
@@ -42,6 +43,7 @@ public class JsonWriter {
|
||||
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}") }
|
||||
if (let dt: DateTime <- value) { return JsonString(dt.format("yyyy-MM-dd HH:mm:ss")) }
|
||||
|
||||
let typeName = TypeInfo.of(value).toString()
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
package simcu::serialization.tests
|
||||
|
||||
import std.collection.*
|
||||
import std.time.*
|
||||
import std.unittest.*
|
||||
import std.unittest.testmacro.*
|
||||
import simcu::serialization.*
|
||||
@@ -55,6 +56,13 @@ class User <: BaseUser {
|
||||
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
|
||||
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 数字 ↔ 字符串字段互转
|
||||
@TestCase
|
||||
public func looseConversion(): Unit {
|
||||
|
||||
Reference in New Issue
Block a user