10 个版本
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.1 | 2022 年 8 月 30 日 |
#1209 in 过程宏
64 每月下载量
在 2 个库中使用(通过 flatty)
55KB
1.5K SLoC
flatty
Flat 消息缓冲区,直接映射到 Rust 类型,无需打包/解包。
概述
当类型占用单个连续内存区域时,称为 flat 类型。这种类型在需要以二进制数据形式存储或发送对象,同时方便访问其内容而不进行序列化/反序列化的情况下非常有用。
此库提供基本的 flat 类型以及创建新的用户定义复合 flat 类型的方法(使用 #[flat]
属性宏),可以像常规 Rust struct
或 enum
一样使用。
此外,该库可以在不使用 std
的情况下使用,甚至可以在不使用 alloc
的情况下使用。
概念
转换
可以使用 as_bytes
(和 unsafe 的 as_mut_bytes
)从 flat 类型的实例中获取二进制表示。此外,可以将字节转换为 flat 类型,请参阅 就地初始化 和 验证。
DST
平面类型可以是动态大小的(例如 FlatVec
),在这种情况下,它利用Rust操作?Sized
类型的能力。用户定义的平面结构体也可以是无大小的(只允许最后一个字段是无大小的)。即使是平面枚举也可以是无大小的,但Rust尚未原生支持它们,因此其内容只能通过返回包含原始枚举内容引用的常规枚举的as_ref
/as_mut
方法来访问。
原地初始化
有大小类型可以像通常的Rust类型一样实例化。但在DST的情况下,Rust不能以通常的方式在栈上构造它,因为其大小在编译时是未知的。相反,我们可以在给定的内存区域上初始化这样的类型。
为此,我们可以使用所谓的emplacer——一种可以在给定的内存上初始化对象的东西。对于有大小类型,其实例也是emplacer。
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
省略验证,但这如果数据无效将导致未定义行为。
可移植性
平面类型保证它在具有相同字节序、对齐和地址宽度的平台上具有相同的二进制表示。如果您需要更强的保证,可以使用Portable
类型——它们在任何平台上都具有相同的二进制表示,并且始终对齐到字节。要创建自己的平面类型以使其可移植,请使用#[flat(portable = true)]
。此外,这还可以用于创建无对齐问题的紧凑平面类型。
示例
您可以在tests
目录中找到创建和使用平面类型的示例。
许可证
根据您的选择,许可为以下之一
- Apache许可证第2版(LICENSE-APACHE或http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT或http://opensource.org/licenses/MIT)
。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义的,您有意提交给作品的所有贡献,将双重许可如上所述,无任何附加条款或条件。
依赖关系
~1.5MB
~35K SLoC