#deserialize #serde #array #big #de #u8 #attributes

serbia

为 Serde 量身定做的无烦恼大数组

5 个版本

0.4.3 2021 年 3 月 28 日
0.4.2 2021 年 3 月 26 日
0.3.0 2021 年 3 月 11 日
0.2.0 2021 年 3 月 11 日
0.1.1 2021 年 3 月 10 日

#37#big

MIT 许可证

31KB
497

Serbia

docs.rs badge crates.io badge Build Status

Serde big arrays. 一个属性宏,使(反)序列化大数组变得轻松,大致遵循David Tolnay 提出的设计

为什么?

我在 request-for-implementation 中看到了这个想法。然后我想出了这个名字。

这个名字太好了。我不得不这么做。不要评判我。

另外:塞尔维亚有一些美味的食物。

但它有什么用?

Serde 只实现了长度最多为 32 的数组的 Serialize/Deserialize。这是由于 Rust 当前的限制——我们不能对数组长度进行泛型处理,因此选择了一个任意上限,并且只生成了到这个上限的实现。

该包提供了一个宏,它可以生成你需要的所有(反)序列化大于此长度的数组的代码。

状态

正在开发中,但功能正常。告诉我缺少什么或有什么问题!

用法

只需在你的类型定义顶部加上 #[serbia]。结构体和枚举都适用!

use serbia::serbia;

#[serbia]
#[derive(Serialize, Deserialize)]
struct S {
    arr_big: [u8; 300],     // custom serialize/deserialize code generated here
    arr_small: [u8; 8],     // no custom code - this is handled by Serde fine
}

#[serbia]
#[derive(Serialize, Deserialize)]
enum E {
    ArrBig([u8; 300]),
    ArrSmall([u8; 22]),
    Mixed([u8; 8], [i32; 44], String),
}

如果 Serbia 看到给定的数组长度是一个常量,它将默认生成自定义序列化和反序列化代码,而不会检查该常量是否大于 32。这是宏的限制。

const BUFSIZE: usize = 22;

#[serbia]
#[derive(Serialize, Deserialize)]
struct S {
    arr: [i32; BUFSIZE],   // custom serialize/deserialize code generated here
    foo: String,
}

跳过字段

如果由于某些原因你不想让 Serbia 为它通常处理的字段生成自定义序列化和反序列化代码,你可以跳过它。

const BUFSIZE: usize = 24;

#[serbia]
#[derive(Serialize, Deserialize)]
struct S {
    #[serbia(skip)]
    arr_a: [u8; BUFSIZE],
    arr_b: [u8; 42],
    arr_small: [u8; 8],
}

如果需要,可以更精细。

const BUFSIZE: usize = 24;

#[serbia]
#[derive(Serialize, Deserialize)]
struct S {
    #[serbia(skip_serializing, skip_deserializing)]
    arr_a: [u8; BUFSIZE],
    arr_b: [u8; 42],
    arr_small: [u8; 8],
}

手动数组长度

你可以使用 #[serbia(bufsize = ... )] 选项为一个字段设置数组长度。这可以用来使类型别名正常工作。常量在这里是有效的!

type BigArray = [i32; 300];

#[serbia]
#[derive(Serialize, Deserialize)]
struct S {
    #[serbia(bufsize = 300)]
    arr_a: BigArray,
    foo: String,
}
const BUFSIZE: usize = 300;
type BigArray = [i32; BUFSIZE];

#[serbia]
#[derive(Serialize, Deserialize)]
struct S {
    #[serbia(bufsize = "BUFSIZE")]
    arr_a: BigArray,
    foo: String,
}

与 Serde 字段属性的交互

Serbia 会检测到某些 Serde 字段属性的使用,并避免生成会导致冲突的代码,而是服从 Serde

    #[serbia]
    #[derive(Debug, Serialize, Deserialize, PartialEq)]
    struct S {
        big_arr: [u8; 40],    // serbia generates code for this
        #[serde(serialize_with="ser", deserialize_with="de")]
        bigger_arr: [u8; 42], // serbia ignores this in favor of the (de)serializers you provided
    }

Serbia 的目的是与 Serde 字段属性友好地协同工作。如果有问题,请创建一个问题或提交一个 PR!

不工作的事情

嵌套类型。

#[serbia]
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct S {
    big_arr: Option<[u8; 300]>,  // no code generated for this nested array
}

塞尔维亚 还未识别 Serde 变体属性,因此可能存在冲突。这可以通过在每个 塞尔维亚 尝试生成自定义(反)序列化代码的字段上使用 #[serbia(skip)] 来解决。

依赖项

~1.5MB
~35K SLoC