simapi_serialization

SimApi 全反射 JSON 序列化库(仓颉版),对齐 .NET System.Text.Json 的用法与注解风格。

  • 免标注:任意类(无参构造 + var 字段)无需实现接口、无需标注,开箱即用
  • 注解@SerializerPropertyName / @SerializerIgnore(对齐 [JsonPropertyName] / [JsonIgnore]
  • 继承支持@SerializerParent 宏解决父类字段序列化(Cangjie 反射限制)
  • API 对齐JsonSerializer.Serialize(obj, JsonOption) / Deserialize<T>(json, JsonOption)

快速开始

引入

[dependencies]
simapi_serialization = { path = "../simapi-serialization" }
import simapi_serialization.*   // 一个 import 全量可用(注解 + 序列化器)

序列化 / 反序列化

class User {
    public var _name: String = ""
    public var _age: Int64 = 0
    public var active: Bool = true
    public var _role: Role = Role.User     // 枚举 → 名字字符串
    public var opt: ?String = None         // OptionSome→值,None→null
    public var _tags: Array<String> = []
    public var addr: Address = Address()   // 嵌套对象
}

let u = User()
u._name = "alice"
u._age = 30

let json = JsonSerializer.Serialize(u)
// { "_name": "alice", "_age": 30, "active": true, "_role": "User", "opt": null, "_tags": [], "addr": {...} }

let u2 = JsonSerializer.Deserialize<User>(json)
// 全部字段回填

注解

class User {
    @SerializerPropertyName["user_name"]
    public var _username: String = ""   // JSON 键用 user_name(对齐 [JsonPropertyName]

    @SerializerIgnore
    public var _temp: String = ""       // 序列化/反序列化忽略(对齐 [JsonIgnore]
}

父类字段序列化(@SerializerParent

背景

Cangjie 反射对实例成员读写有声明类严格校验declaringClass != TypeInfo.of(instance)), 父类字段无法用子类实例读写。@SerializerParent 宏在编译期生成静态导出/导入方法, 方法体内用静态类型访问字段,绕开该限制。

用法

import simapi_serialization.*
import simapi_serialization.macros.*

@SerializerParent                 // 标注在父类上;非 open 类自动补 open
class BaseUser {
    public var _id: String = ""
    public var _createdAt: String = ""
}

class User <: BaseUser {          // 子类零改动
    public var _name: String = ""
}

let u = User()
u._id = "u-1"
u._name = "alice"

let json = JsonSerializer.Serialize(u)
// 输出包含父类字段:{ "_name": "alice", "_id": "u-1", "_createdAt": "" }

特性

特性 说明
自动补 open 非 open 类标注宏后自动可继承
多层继承 沿 superClass 链逐层调用;中间层无宏自动跳过
注解生效 父类字段的 @SerializerPropertyName / @SerializerIgnore 同样生效
向后兼容 无宏的类行为不变

宏生成的方法

// 宏为父类自动生成(可直接调用):
BaseUser.exportJsonFields(instance)                  // HashMap<String, Any>
BaseUser.importJsonFields(instance, json)            // 回填字段

选项(JsonOption

选项 默认 说明
propertyNamingPolicy CamelCase 字段命名策略
enumAsString true 枚举序列化为名字
maxDepth 64 递归深度上限(超过抛异常)
let opt = JsonOption()
opt.propertyNamingPolicy = PropertyNamingPolicy.SnakeCase   // userName → user_name
opt.maxDepth = 16

let json = JsonSerializer.Serialize(u, opt)

命名策略(PropertyNamingPolicy

策略 效果
Keep 字段名原样(_username_username
CamelCase 首字母小写(Namename;下划线字段保持原样)
SnakeCase 大写转下划线(userNameuser_name

注:不剥除字段名前导下划线——_name 原样输出 _name

支持的类型

类别 说明
基础类型 String / Bool / 全部整数 / 浮点 / Rune
集合 Array<T> / ArrayList<T> / HashSet<T>
字典 HashMap<K, V>(键须可转字符串)
Option<T> Some(x) → 值;Nonenull
枚举 构造器名(Role.Admin"Admin"
普通类 无参构造 + var 字段;嵌套对象递归

宽松类型转换(反序列化)

JSON 数字 ↔ 字符串字段自动互转:Deserialize<String>("42")"42" Deserialize<Int64>("\"42\"")42

已知限制

  • 父类字段序列化需父类标注 @SerializerParent(见上文;Cangjie 反射平台限制)
  • 反序列化要求目标类型无参构造、字段为 varlet 只读字段跳过)
  • 集合/字典元素类型需为支持的类型
  • 泛型父类暂不支持

包结构

src/
├── SimApiSerialization.cj      // 根锚点:public import common.* + json.*
├── common/                     // XML/JSON 共用
│   ├── Annotations.cj          // @SerializerPropertyName / @SerializerIgnore
│   ├── ReflectionCache.cj      // 字段元数据 + 继承链缓存
│   └── NamingPolicy.cj         // PropertyNamingPolicy
├── json/                       // JSON 序列化
│   ├── JsonSerializer.cj       // 公开 API
│   ├── JsonWriter.cj / JsonReader.cj
│   ├── JsonOption.cj
│   └── JsonSerializer_test.cj  // 单元测试(cjpm test16 用例)
└── macros/                     // @SerializerParent 宏
    └── SerializerParentMacro.cj

测试

cjpm test
# TOTAL: 16, PASSED: 16

覆盖:基础类型、对象字段输出、注解、Option、集合、HashMap、枚举、命名策略、 父类字段(宏)、多层继承、maxDepth、宽松类型转换。

设计参考

  • API 对齐 .NET System.Text.JsonJsonSerializer.Serialize/Deserialize + JsonSerializerOptions
  • 注解对齐 [JsonPropertyName] / [JsonIgnore]
  • 父类方案参考 soulsoft_serialization 的「宏生成静态类型字段代码」思路 (详见 docs/父类字段序列化方案.md
S
Description
SimApi 全反射 JSON 序列化库(仓颉版),对齐 .NET System.Text.Json 的用法与注解风格。
Readme
91 KiB
Languages
Cangjie 100%