29 个发布版本

0.9.0-alpha.02024年3月9日
0.8.1 2023年8月17日
0.8.0 2022年8月16日
0.7.1 2022年6月15日
0.0.1 2017年7月30日

#18 in 编码

Download history 205621/week @ 2024-04-29 212141/week @ 2024-05-06 238032/week @ 2024-05-13 225680/week @ 2024-05-20 232657/week @ 2024-05-27 252484/week @ 2024-06-03 249913/week @ 2024-06-10 227741/week @ 2024-06-17 236587/week @ 2024-06-24 200525/week @ 2024-07-01 262709/week @ 2024-07-08 266753/week @ 2024-07-15 261816/week @ 2024-07-22 278491/week @ 2024-07-29 256947/week @ 2024-08-05 277892/week @ 2024-08-12

1,090,106 每月下载量
用于 2,195 个crate(553个直接使用)

MIT/Apache

275KB
7K SLoC

Rusty 对象表示法

MSRV Crates.io Docs

CI Coverage Fuzzing

Matrix

RON 是一种简单易读的数据序列化格式,看起来类似于 Rust 语法。它设计用于支持 Serde 的数据模型,因此支持结构体、枚举、元组、数组、泛型映射和原始值。

示例

GameConfig( // optional struct name
    window_size: (800, 600),
    window_title: "PAC-MAN",
    fullscreen: false,

    mouse_sensitivity: 1.4,
    key_bindings: {
        "up": Up,
        "down": Down,
        "left": Left,
        "right": Right,

        // Uncomment to enable WASD controls
        /*
        "W": Up,
        "S": Down,
        "A": Left,
        "D": Right,
        */
    },

    difficulty_options: (
        start_difficulty: Easy,
        adaptive: false,
    ),
)

RON 语法概述

  • 数字:423.140xFF0b0110
  • 字符串:"Hello""with\\escapes\n"r#"raw string, great for regex\."#
  • 字节字符串:b"Hello"b"with \x65\x73\x63\x61\x70\x65\x73\n"br#"raw, too"#
  • 布尔值:truefalse
  • 字符:'e''\n'
  • 可选类型: Some("string")Some(Some(1.34))None
  • 元组: ("abc", 1.23, true)()
  • 列表: ["abc", "def"]
  • 结构体: ( foo: 1.0, bar: ( baz: "I'm nested" ) )
  • 映射: { "arbitrary": "keys", "are": "allowed" }

注意: Serde的数据模型将固定大小的Rust数组表示为元组(而不是列表)

RON还支持几个扩展,这些扩展的文档在此处

规范

RON的正式和完整语法在此处

还有一个非常基础的、正在进行中的规范在维基页面上

为什么选择RON?

JSON中的示例

{
   "materials": {
        "metal": {
            "reflectivity": 1.0
        },
        "plastic": {
            "reflectivity": 0.5
        }
   },
   "entities": [
        {
            "name": "hero",
            "material": "metal"
        },
        {
            "name": "monster",
            "material": "plastic"
        }
   ]
}

相同的RON示例

Scene( // class name is optional
    materials: { // this is a map
        "metal": (
            reflectivity: 1.0,
        ),
        "plastic": (
            reflectivity: 0.5,
        ),
    },
    entities: [ // this is an array
        (
            name: "hero",
            material: "metal",
        ),
        (
            name: "monster",
            material: "plastic",
        ),
    ],
)

注意RON相对于JSON的优势

  • 允许尾随逗号
  • 单行和多行注释
  • 字段名称不需要引号,因此更简洁
  • 可选的结构体名称提高了可读性
  • 支持枚举(并且比它们的JSON表示更简洁)

快速入门

Cargo.toml

[dependencies]
ron = "0.8"
serde = { version = "1", features = ["derive"] }

main.rs

use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)]
struct MyStruct {
    boolean: bool,
    float: f32,
}

fn main() {
    let x: MyStruct = ron::from_str("(boolean: true, float: 1.23)").unwrap();

    println!("RON: {}", ron::to_string(&x).unwrap());

    println!("Pretty RON: {}", ron::ser::to_string_pretty(
        &x, ron::ser::PrettyConfig::default()).unwrap(),
    );
}

工具

编辑器 插件
IntelliJ intellij-ron
VS Code a5huynh/vscode-ron
Sublime Text RON
Atom language-ron
Vim ron-rs/ron.vim
EMACS emacs-ron

限制

RON不是设计成完全自描述的格式(与JSON不同),因此当使用deserialize_any而不是其类型替代品时,不能保证其工作。特别是,以下Serde属性只有有限的兼容性

  • #[serde(tag = "tag")],即内部标记的枚举[^serde-enum-hack]
  • #[serde(tag = "tag", content = "content")],即相邻标记的枚举[^serde-enum-hack]
  • #[serde(untagged)],即未标记的枚举[^serde-enum-hack]
  • #[serde(flatten)],即将结构体展平为映射[^serde-flatten-hack]

虽然具有这些属性之一的数据结构通常应通过 RON 进行往返,但有一些限制[^serde-restrictions],其文本表示可能并不总是符合您的期望

  • ron 只支持映射中展开到结构体的字符串键
  • 内部(或相邻)标记或未标记的枚举变体,或#[serde(flatten)]的域不得包含
    • 结构体名称,例如通过启用#[enable(explicit_struct_names)]扩展或PrettyConfig::struct_names设置
    • 新类型
    • 零长度数组 / 元组 / 元组结构体 / 结构体 / 元组变体 / 结构体变体
      • Option具有#[enable(implicit_some)]不得包含这些中的任何一种或单元、单元结构体或未标记的单元变体
    • 仅有一个字段的外部标记元组变体(不是新类型变体)
    • 仅有一个元素的元组或数组或元组结构体不支持在具有#[enable(unwrap_variant_newtypes)]的新类型变体中(包括Some
    • 一个ron::value::RawValue
  • 未标记的元组/结构体变体没有字段不支持
  • 当启用#![enable(unwrap_variant_newtypes)]扩展时,不支持仅有一个字段(不是newtype变体)的无标签元组变体
  • 使用PrettyConfig序列化ron::value::RawValue可能会添加前导和尾随空白和注释,这些在反序列化时由ron::value::RawValue吸收

此外,serde对数据进行往返操作施加以下限制

  • 包含#[serde(flatten)]化字段的
    • 结构体或结构体变体只能序列化为映射,并从映射反序列化
    • 不得包含重复字段/键,例如内部结构体字段与外部结构体或内部结构体字段匹配的情况
    • 不得包含超过一个(在所有展开结构体的超结构体中)#[serde(flatten)]化映射字段,该字段收集所有未知字段
    • 如果它们包含一个#[serde(flatten)]化映射,则不得包含
      • 一个不是展开本身但包含一些展开字段并被展开到外部结构体(变体)中的结构体
      • 包含一些展开字段的无标签结构体变体
      • 展开的外部标记新类型、元组或结构体变体,展开的内部标记单元、新类型或结构体变体,或任何相邻标记的展开变体
      • 展开的标记结构体
  • 内部(或相邻)标记或未标记的枚举变体,或#[serde(flatten)]的域不得包含
    • i128u128
  • 内部标记的新类型变体和#[serde(flatten)]化字段不得包含
    • 无标签新类型变体内部的单元或单元结构体
    • 无标签的单元变体
  • 内部标记的新类型变体,它们与其他字段一起#[serde(flatten)]化,不得包含
    • 单元或单元结构体或无标签的单元变体

如果您遇到上述限制中没有列出但仍然破坏的情况,请提交一个新问题

尽管 RON 与 Rust 类似,保证了 Rust -> RON -> Rust 的往返操作,但对于使用非 deserialize_any 基于实现的 Rust 类型,RON 目前还没有对通过 ron::Value 的往返操作做出任何保证。例如,即使 RON -> Rust 可以正常工作,RON -> ron::Value -> Rust,或者 RON -> ron::Value -> RON -> Rust 可能无法正常工作。我们计划在 RON 的下一个版本中改进 ron::Value,尽管这项工作部分受制于 serde#1183

[^serde-enum-hack]: 反序列化内部、相邻或未标记的枚举需要检测 serde 的内部 serde::__private::de::content::Content 内容类型,以便 RON 能够在 serde 的内部 JSON-like 格式中描述反序列化后的数据结构。这种检测仅适用于枚举上的自动派生 Deserialize 实现。有关更多详细信息,请参阅 #451

[^serde-flatten-hack]: 从映射反序列化扁平化结构需要结构体的 Visitor::expecting 实现格式化以字符串开头 "struct "。这适用于结构体上的自动派生 Deserialize 实现。有关更多详细信息,请参阅 #455

[^serde-restrictions]: 大多数这些限制目前受制于 serde#1183,该限制限制了非自我描述格式通过内部(或相邻)标记或未标记的枚举或 #[serde)] 化字段往返特定于格式的信息。

许可证

RON 在 Apache-2.0 和 MIT 下双重许可。

有意提交以包含在作品中的任何贡献都必须以相同的双重许可条款提供。

依赖关系

~0.7–1.5MB
~32K SLoC