23 个版本 (12 个重大更新)
0.20.1 | 2024年4月25日 |
---|---|
0.19.0 | 2024年4月25日 |
0.18.2 | 2024年1月5日 |
0.17.2 | 2023年12月29日 |
0.9.1 | 2023年5月11日 |
#264 in 解析实现
33 每月下载量
130KB
2.5K SLoC
SSD - 简单服务和数据描述
关于 - 什么是 SSD?
首先,它应该是一种描述数据结构和服务的格式。此外,它还提供了一些工具来处理上述格式,简化了编写自定义代码生成器的过程。
历史 - 为什么我要创建这个?
在我工作的一个公司中,我们用 Delphi 编程,我们有一堆需要序列化的结构。在 Delphi 中序列化数据需要手动构建对象,这很容易出错,并且使用起来很麻烦。因此,我编写了一个小型的(封闭源代码)代码生成器,使用 D、SDLang 和模板引擎。
几个月后,很明显,模板引擎使得某些事情变得更加难以维护和推理。因此,我决定用 C# 重新编写整个系统。这次我使用了一个自定义解析器来允许更流畅的数据文件,并且我按照这种方式构建了生成器,即实际的代码生成将通过 C# DLL 完成。这样,如果你愿意,仍然可以使用模板引擎,只需将其嵌入 DLL 并使用即可。
我还被允许开源所有内容,除了我们内部使用的自定义代码生成插件。源代码可以在以下位置找到: https://github.com/hardliner66/codegenerator
尽管如此,我仍然不太满意,因为跨平台使用代码生成器仍然很复杂,需要 mono。经过一段时间,我开始更多地使用 Rust,并发现了 WebAssembly,这激发了我进行第三次尝试。这次的目标是允许插件用 wasm 编写,以便人们可以用他们熟悉的任何语言编写生成器。
最初,我将其命名为 SSDCG,代表 Simple Service 和 Data description format and Code Generator(简单服务和数据描述格式及代码生成器)。但是这个名字很难记住,而且重点始终更多地放在统一的数据描述语言上,代码生成是该语言的主要用例。
该项目已经超越了最初的目标,不仅支持WASM,还支持Rhai(脚本语言)和三种不同的模板引擎,它们都可以使用相同的统一数据模型。一旦您的模型编写完成,您可以选择最适合您需求的任何技术来生成模型中的任何内容。
数据格式也从旧版本中发展了很多,支持描述数据类型、枚举、导入、具有函数和事件的函数,以及所有这些的自定义属性,以实现更多定制。它的设计类似于简化版的Rust,因为我个人非常喜欢这种语法,而且它是一个自然的选择,因为整个项目都是用Rust编写的。
注意:破坏性变更!
只要crate版本低于1.0.0,就会预期出现破坏性变更。
迄今为止的破坏性变更
版本 | 变更 |
---|---|
0.8.0 | 我将语法从 handles 更改为 fn ,并将字段从 handlers 更改为 functions 。 |
0.9.0 | 将crate重命名为ssd |
0.10.0 | 将AST移动到单独的crate中,以便在wasm插件中使用 |
0.11.0 | 限制注释可以出现的位置。这简化了自动格式化。 |
0.12.0 | 将SsdcFile重命名为SsdFile,以与项目名称匹配 |
0.13.0 | 文档注释现在是公开数据的正式部分。 |
0.14.0 | 移除liquid模板以简化代码并去除代码重复。无论如何,Tera似乎足够接近。 |
0.15.0 | 将Ron放在功能门后面,因为我之前已经有一些问题,并提供了rsn(类似格式)。 |
0.16.0 | 将属性的表示从indexmap更改为元组的vec。 |
0.17.0 | 将SsdFile 重命名为SsdModule 。从默认功能中移除了wasm 和tera 。 |
0.18.0 | 将typ 字段重命名为type |
功能
- 自定义描述语言(基本功能已完成,但仍有一些功能缺失)
- 导入
- 数据类型
- 枚举
- 服务
- 自定义属性
- 这些可以用来实现语言中缺失的自定义功能
- 某些功能将在以后添加,而其他功能将始终依赖于属性,因为它们不够通用
- 列表
- 固定大小(
property: 5 of u8
) - 动态大小(
property: list of u8
)
- 固定大小(
- 泛型
- 自动格式化
- 脚本语言
- Rhai
- 通过PyO3的Python
- 模板引擎
- Wasm(通过extism)
- 用于与其他工具(JSON、Yaml、Tомl)一起使用的数据导出
- 使用原始数据(JSON、Yaml、Tомl、Rsn)而不是预定义的ssd格式
- 这允许在处理来自其他地方的数据时使用相同的工具
- 基本健全性检查
Cargo功能
default
是wasm
、tera
、handlebars
tera
启用对tera模板的支持handlebars
启用对handlebars模板的支持wasm
启用对wasm插件的支持ron
启用对ron
的支持all
启用一切
数据规范
它基本上是“所见即所得”,如此处所示
- data/test.svc查看描述语言的样子。
目前唯一的限制是,自动格式化总是将注释放在元素之后的元素之前。这意味着以下
data Test {
a: i32, /// test
b: i32,
}
将被格式化为
data Test {
a: i32,
/// test
b: i32,
}
试用一下
要试用,请安装命令行工具,克隆仓库,并使用以下命令:
ssd generate rhai example-generators/cpp-like.rhai data/test.svc
示例
您可以查看文件
- example-generators/cpp-like.rhai,查看生成器可能的样子。
- example-generators/cpp-like.rhai.tym,查看类型映射文件的样子。
- example-generators/simple.hbs,查看简单的 Handlebars 模板的样子。
- example-generators/simple.tera,查看简单的 Tera 模板的样子。
- example-generators/wasm-example/README.md,查看简单的 Rust (wasm) 生成器的样子。
安装
可以通过 cargo 安装
cargo install --locked ssd
或者从 发布页面 下载预构建包。
用法
通用
➜ ssd help
Simple Service Description
Usage: ssd [COMMAND]
Commands:
debug Print debug representation of the parsed file
pretty Pretty print the parsed file
generate Generate source code
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
生成
➜ ssd generate help
Generate source code
Usage: ssd generate <COMMAND>
Commands:
rhai Use a rhai based generator
handlebars Use a handlebars based template. https://handlebars.node.org.cn/
tera Use a tera based template. https://tera.netlify.app/
wasm Use a wasm based generator
data Output as serialized data for external use
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
Rhai
➜ ssd generate rhai --help
Use a rhai based generator
Usage: ssd generate rhai [OPTIONS] <SCRIPT> <FILE>
Arguments:
<SCRIPT>
The script to use to generate the file
<FILE>
which file to use
Options:
-d, --debug
Enables debug mode (print and debug function in the script)
--no-map
do not use type mappings
--typemap <TYPEMAP>
A file containing type mappings.
If a file with the same name as the script file, but with the extension tym, it will be used automatically.
e.g.: If there is a file `/generator/script.rhai` and a corresponding `/generator/script.tym`, it will get
used automatically.
-r, --raw
use raw data file as input instead of the ssd data format
-o, --out <OUT>
The file which should get written with the output from the generator
-h, --help
Print help (see a summary with '-h')
Handlebars
别名:ssd generate hbs
➜ ssd generate handlebars --help
Use a handlebars based template. https://handlebars.node.org.cn/
Usage: ssd generate handlebars [OPTIONS] <TEMPLATE> <FILE>
Arguments:
<TEMPLATE>
The template to use to generate the file
<FILE>
which file to use
Options:
--no-map
do not use type mappings
--typemap <TYPEMAP>
A file containing type mappings.
If a file with the same name as the script file, but with the extension tym, it will be used automatically.
e.g.: If there is a file `/generator/script.rhai` and a corresponding `/generator/script.tym`, it will get
used automatically.
-r, --raw
use raw data file as input instead of the scd data format
-o, --out <OUT>
The file which should get written with the output from the generator
-h, --help
Print help (see a summary with '-h')
Tera
➜ ssd generate tera --help
Use a tera based template. https://tera.netlify.app/
Usage: ssd generate tera [OPTIONS] <TEMPLATE_DIR> <TEMPLATE_NAME> <FILE>
Arguments:
<TEMPLATE_DIR>
Glob path for where to search for templates
<TEMPLATE_NAME>
The template to use to generate the file
<FILE>
which file to use
Options:
--no-map
do not use type mappings
--typemap <TYPEMAP>
A file containing type mappings.
If a file with the same name as the script file, but with the extension tym, it will be used automatically.
e.g.: If there is a file `/generator/script.rhai` and a corresponding `/generator/script.tym`, it will get
used automatically.
-r, --raw
use raw data file as input instead of the scd data format
-o, --out <OUT>
The file which should get written with the output from the generator
-h, --help
Print help (see a summary with '-h')
Wasm
➜ ssd generate wasm --help
Use a wasm based generator
Usage: ssd generate wasm [OPTIONS] <WASM> <FILE>
Arguments:
<WASM>
The wasm plugin to use to generate the file
<FILE>
which file to use
Options:
--no-map
do not use type mappings
--typemap <TYPEMAP>
A file containing type mappings.
If a file with the same name as the script file, but with the extension tym, it will be used automatically.
e.g.: If there is a file `/generator/script.rhai` and a corresponding `/generator/script.tym`, it will get
used automatically.
-r, --raw
use raw data file as input instead of the scd data format
-o, --out <OUT>
The file which should get written with the output from the generator
-h, --help
Print help (see a summary with '-h')
Python / PyO3
通过 pip 安装
pip3 install py_ssd
用法
>>> import py_ssd
>>> model = py_ssd.parse_file(".", "./data/test.svc")
[src/parser.rs:509] key = "Rect"
# the namespace is generated from the file path (second parameter),
# with the base path removed (first parameter)
>>> model['namespace']
{'components': ['data', 'test']}
>>> model['data_types'].keys()
dict_keys(['Rect'])
>>> model['data_types']['Rect']['properties']['x']
{'typ': {'components': ['i32']}, 'attributes': [{'name': {'components': ['test']}, 'parameters': []}], 'comments': []}
依赖
~11–27MB
~436K SLoC