#json-schema #generate-json #schema #json #codegen

jtd-derive

从Rust类型生成JSON类型定义模式

4个版本

0.1.4 2024年2月3日
0.1.3 2023年11月12日
0.1.2 2023年11月12日
0.1.1 2022年12月27日
0.1.0 2022年12月27日

#531 in 编码

MIT/Apache

56KB
1K SLoC

jtd-derive — 构建状态 许可证 版本 文档

从Rust类型生成JSON类型定义模式。

状态

基本可用,但缺少重要的功能,如更好的serde支持。

API是不稳定的。在次要版本升级之间可能会发生重大更改。

为什么?

因为Typedef在最小化和无歧义性方面看起来真的很不错。特别是,那些生成基于JSON的API和相关接口描述语言文件(预期这些文件将被用于代码生成)的系统可以使用类似的东西。在这些敏感区域中,功能膨胀可能不是一个好主意。

这个crate希望使事情变得更好,因为Rust项目可以将语言无关的类型定义作为Rust代码而不是使用不同语法的单独事物。

替代方案

JSON Schema

JSON Schema通常被吹捧为更普遍接受的解决方案。问题是,它是一个针对不同问题的解决方案。JSON Schema旨在非常具有表现力,并且对于验证JSON数据与复杂约束非常有效。

如果您预计代码生成将是您的重大需求,但还想提供JSON Schemas,请考虑使用Typedef并编写一个Typedef -> JSON Schema生成器。这样,代码生成消费者仍然可以从中受益于Typedef的简单性。

serde支持但jtd_derive不支持的类型

  • struct Foo;这样的单元结构
  • 元组结构体,例如 struct Foo(u32, u32)struct Foo()
    • 新类型结构体是一个例外。在JSON中表示为内部值,在Typedef中表示为内部模式。如果一个结构体恰好有一个未命名的字段,那么它被认为是新类型,例如 struct Foo(u32)
  • 采用C结构体风格的struct,但没有字段,例如 struct Foo {}
  • 具有混合变体“种类”的枚举,例如。
    enum Foo {
        Bar,            // unit variant
        Baz { x: u32 }, // struct variant
    }
    
  • 具有元组变体的枚举,例如。
    enum Foo {
        Bar(u32),
        Baz(String),
    }
    
  • 具有与内部标记不同的serde表示方式的枚举 - 这是Typedef坚持的枚举表示方式。
  • 元组 - 作为可能异构的数组进行序列化,但Typedef仅支持同构的。
  • Bound - 一个变体被序列化为字符串,其他作为对象。Typedef不支持这种堕落的复杂结构。
  • Duration - 使用u64,这是Typedef不支持的数据类型。
  • SystemTime - 原因同上。
  • PhantomData - 尝试序列化它似乎很愚蠢!在模式中也没有良好的方式来指定null字面量。
  • Result - OkErr变体通常具有不同的形式,这些形式在Typedef中无法表示。
  • OsStrOsStringPathPathBuf - 我并不完全理解这些类型的细微差别。我不确定是否应该鼓励人们在Rust FFI之外的API边界使用这些类型。如果您想讨论,请随时打开一个问题,描述您的用例和想法。

这一切可能看起来非常受限,但请记住,Typedef的目的不是具有广泛的表达性和能够描述Rust类型系统可以描述的任何内容。这个想法是鼓励通用的API和适合代码生成的模式。

您在这里缺少的每一份表达性都是您消费者的一丝安慰。

许可证

双许可,可选使用MIT和Apache 2.0,类似于大多数Rust项目。

依赖项

~1.3–2.5MB
~55K SLoC