hongtools:提供宏工具集,自动实现接口、简化开发、支持元编程与资源嵌入

通过@HTSerializable、@HTEquatable等宏自动实现常用接口,@Lazy简化开发,@Nameof增强元编程能力,@EmbedString/Bytes实现资源嵌入,提升开发效率。【此简介由AI生成】

分支2Tags3
文件最后提交记录最后更新时间
2 年前
1 年前
1 年前
1 年前
1 年前
2 年前
1 年前
2 年前
2 年前
1 年前

Hongtools / 红兔

1 介绍

1.1 项目特性

  1. 自动实现接口 - Hongtools 提供了 @HTSerializable@HTEquatable@HTToString等宏,能够自动实现一些常用接口,避免代码冗长。
  2. 元编程能力 - Hongtools 提供了 @Nameof 宏,提高操作代码的能力,使开发者能以更高级的方式操作代码。
  3. 简化开发 - Hongtools 提供了 @Lazy 宏,简化常用代码实现。
  4. 资源嵌入 - Hongtools 提供了 @EmbedString@EmbedBytes 资源嵌入宏,可将资源文件嵌入到变量中。

1.2 项目计划

  1. 2024 年 9 月发布 0.1.0 版本,实现基本功能。
  2. 2024 年 10 月发布 0.2.0 版本,支持对 @HTSerializable@HTEquatable@HTToString 等宏的细节进行自定义。

2 架构

2.1 项目结构

.
├── README.md
├── LICENSE
├── CHANGELOG
├── cjpm.toml
├── doc                     # 文档
|   └── readme-image
└── src
    ├── macros              # 宏实现
    └── test                # 测试代码

2.2 接口说明

hongtools 目前支持以下的宏:

名称 类型 用途 使用位置
@HTSerializable 接口实现 自动实现 Serializable<T> 接口,可用于与 JSON 互转等序列化场景。 类前
@HTEquatable 接口实现 自动实现 Equatable<T> 接口,可用于比较两个类内成员是否完全相同。 类前
@HTToString(开发中) 接口实现 自动实现 ToString 接口,可用于将类转换为可打印的字符串。 类前
@HTHashable 接口实现 自动实现 Hashable 接口,可用于计算类的组合哈希值。 类前
@Lazy 开发简化 自动将类中的成员转化为懒加载成员。 成员前
@Nameof 元编程 获取标识符对应的名称字符串。 表达式
@EmbedString 资源嵌入 将资源文件作为 UTF-8 字符串嵌入到变量内 表达式
@EmbedBytes 资源嵌入 将资源文件作为字节数组嵌入到变量内 表达式

3 使用说明

3.1 编译构建(Win/Linux/Mac)

cjpm build

3.2 功能示例

3.2.1 自动实现 Serializable 接口,并进行 JSON 的序列化和反序列化

import hongtools.macros.*
import encoding.json.*

@HTSerializable
class CustomClass {
    CustomClass(
        var a: String,
        let b: Int
    ) {}
}

main() {
    let obj = CustomClass("test", 114)
    let json = obj.serialize().toJson().toJsonString()
    // serialized json: {
    //   "a": "test",
    //   "b": 114
    // }
    println("serialized json: ${json}")
    let dm = DataModel.fromJson(JsonValue.fromStr(json))
    let deserializedObj = CustomClass.deserialize(dm)
    // deserialized obj:
    //     a = test
    //     b = 114
    println("deserialized obj:")
    println("    a = ${deserializedObj.a}")
    println("    b = ${deserializedObj.b}")
}

3.2.2 自动实现 Equatable 接口,用于判断对象是否相等

import hongtools.macros.*
@HTEquatable
class CustomClass {
    CustomClass(
        var a: String,
        let b: Int
    ) {}
}

main() {
    // true
    println(CustomClass("114", 514) == CustomClass("114", 514))
    // false
    println(CustomClass("114", 514) != CustomClass("114", 514))
    // false
    println(CustomClass("114", 514) == CustomClass("114", 1919810))
    // true
    println(CustomClass("114", 514) != CustomClass("114", 1919810))
}

3.2.3 自动实现 Hashable 接口,用于生成类的组合哈希值

import hongtools.macros.*

@HTHashable
class CustomClass {
    CustomClass(
        var a: String,
        let b: Int
    ) {}
}

main() {
    // -6942042951886088022
    println(CustomClass("114", 514).hashCode())
}

3.2.4 将类的成员转换为懒加载值,支持线程安全、线程不安全两种声明方式

import hongtools.macros.*

func getC() {
    "c"
}

class CustomClass {
    // 默认线程安全
    @Lazy[factory = { => 1}] var a: Int
    @Lazy[factory = { => "b"}, threadSafe = false] var b: String
    @Lazy[factory = getC] static var c: String
}

main() {
    let c = CustomClass()
    // 1
    println(c.a)
    // b
    println(c.b)
    // c
    println(CustomClass.c)
}

3.2.5 获取标识符字符串,支持类名、变量等

import hongtools.macros.*

class CustomClass {
    CustomClass(
        var a: String
    ) {}
    prop p: String {
        get() {
            "p"
        }
    }
}
func f() {}
var v = 1

main() {
    // class name: CustomClass
    println("class name: ${@Nameof(CustomClass)}")
    // member name: a
    println("member name: ${@Nameof(CustomClass.a)}")
    // prop name: p
    println("prop name: ${@Nameof(CustomClass.p)}")
    // func name: f
    println("func name: ${@Nameof(f)}")
    // var name: v
    println("var name: ${@Nameof(v)}")

}

3.2.6 资源文件嵌入

package foo

import hongtools.macros.*

main() {
    // 将会打印当前项目的 cjpm.toml 文件内容
    println(@EmbedString("cjpm.toml"))
    
    // 将会打印当前项目的 cjpm.toml 文件内容的字节数组
    println(@EmbedBytes("cjpm.toml"))
}

⚠️ 受宏本身的限制,如果当前正在开发的项目为第三方库(可能会被其他项目引入),需要使用 @EmbedString["模块名"]("路径") 指定本项目模块名,否则无法进行定位。示例如下:

// 项目 foo
package foo.bar

import hongtools.macros.*

public let cjpmStr: @EmbedString["foo"]("cjpm.toml")
public let cjpmBytes: @EmbedBytes["foo"]("cjpm.toml")
// 项目 caller
package caller

import foo.bar.*

main() {
    // 将会打印 foo 项目的 cjpm.toml 文件内容
    println(cjpmStr)
    // 将会打印 foo 项目的 cjpm.toml 文件内容的字节数组
    println(cjpmBytes)
}

4 参与贡献

本项目由 SIGCANGJIE / 仓颉兴趣组 实现并维护。技术支持和意见反馈请提Issue。

本项目是仓颉兴趣组 二星级里程碑项目

本项目基于 MIT License,欢迎给我们提交PR,欢迎参与任何形式的贡献。

本项目committer:@PermissionDog@yishengTH

This project is supervised by @zhangyin-gitcode.

项目介绍

通过@HTSerializable、@HTEquatable等宏自动实现常用接口,@Lazy简化开发,@Nameof增强元编程能力,@EmbedString/Bytes实现资源嵌入,提升开发效率。【此简介由AI生成】

定制我的领域