#序列化 #tera 模板 #数据 #模板生成器 #模板引擎 #脚本语言 #数据结构

bin+lib ssd

一种服务和数据描述格式,以及基于 rhai 脚本和模板的代码生成器

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 中序列化数据需要手动构建对象,这很容易出错,并且使用起来很麻烦。因此,我编写了一个小型的(封闭源代码)代码生成器,使用 DSDLang 和模板引擎。

几个月后,很明显,模板引擎使得某些事情变得更加难以维护和推理。因此,我决定用 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。从默认功能中移除了wasmtera
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功能

  • defaultwasmterahandlebars
  • tera启用对tera模板的支持
  • handlebars启用对handlebars模板的支持
  • wasm启用对wasm插件的支持
  • ron启用对ron的支持
  • all启用一切

数据规范

它基本上是“所见即所得”,如此处所示

目前唯一的限制是,自动格式化总是将注释放在元素之后的元素之前。这意味着以下

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

示例

您可以查看文件

安装

可以通过 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