9 个版本
0.1.0-rc.4 | 2023年11月8日 |
---|---|
0.1.0-rc.2 | 2023年8月22日 |
0.1.0-rc.0 | 2023年6月13日 |
0.1.0-alpha.7 | 2023年5月18日 |
0.1.0-alpha.2 | 2022年9月9日 |
#1353 in Rust 模式
在 2 个crate中使用 (通过 flatty)
59KB
1.5K SLoC
flatty
Flat 消息缓冲区,可以直接映射到 Rust 类型,无需打包/解包。
概述
当类型占用单个连续内存区域时,称为 flat 类型。当您需要以二进制数据的形式存储或发送此类对象,同时又有方便的方式访问其内容而无需序列化/反序列化时,此类类型非常有用。
该crate提供基本的 flat 类型以及创建新的用户定义复合 flat 类型的方法(使用 #[flat]
属性宏),这些类型可以像常规 Rust struct
或 enum
一样使用。
此外,该crate也可以在不使用 std
的情况下使用,甚至不使用 alloc
。
概念
转换
可以使用 as_bytes
(以及不安全的 as_mut_bytes
)从 flat 类型的实例获取二进制表示。还可以将字节转换为 flat 类型,请参阅就地初始化和验证。
DST
flat 类型可以是动态大小的(如 FlatVec
),在这种情况下,它利用 Rust 操作 ?Sized
类型的能力。用户定义的 flat 结构也可以是无大小的(只允许最后一个字段是无大小的)。甚至 flat 枚举也可以是无大小的,但 Rust 尚未原生支持它们,因此其内容只能通过返回包含对原始枚举内容引用的常规枚举的 as_ref
/as_mut
方法来访问。
就地初始化
可以像常规 Rust 类型一样实例化有大小类型。但在 DST 的情况下,由于编译时不知道其大小,Rust 不能像往常一样在栈上构造它。相反,我们可以在给定的内存区域上初始化此类类型。
为此,我们可以使用所谓的填充器 - 可以在给定内存上初始化对象的东西。对于有大小类型,其实例也是填充器。
Emplacer 可用于对原始字节应用 new_in_place
,或使用 assign_in_place
替换现有结构体内容。此外,某些类型具有默认的 emplacer,可以通过 default_in_place
初始化为默认状态。
验证
并非任何字节的组合都是平面类型的有效表示。例如,Bool
只有两种有效状态:0
和 1
,或者 FlatVec
的长度不能大于其容量。可以使用 validate
来检查数据是否适用于特定平面类型,或者 from_bytes
/from_mut_bytes
也会进行此类检查。
当你信任你的数据时,可以使用不安全的 from_bytes_unchecked
/from_mut_bytes_unchecked
跳过验证,但数据无效时这将导致未定义行为(UB)。
可移植性
平面类型保证在具有相同字节序、对齐和地址宽度的平台上具有相同的二进制表示。如果您需要更强的保证,可以使用 Portable
类型 - 它们在 任何 平台上都具有相同的二进制表示,并且始终对齐到字节。要使自己的平面类型可移植,请使用 #[flat(portable = true)]
。此外,这也可以用于创建无对齐问题的紧凑平面类型。
示例
您可以在 tests
目录中找到如何创建和使用平面类型的示例。
许可
根据您的选择,许可如下:
- Apache License, Version 2.0 (LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
。
贡献
除非您明确声明,否则根据 Apache-2.0 许可证定义的,您提交给包含在该作品中的任何有意贡献,都应如上所述双重许可,而不附加任何额外的条款或条件。
依赖关系
~185KB