#endian #conversion #serialization #primitive #representation #traits #byte

endian_trait

一个可以应用于大多数类型的字节序转换特性

7 个版本 (破坏性更新)

使用旧的 Rust 2015

0.6.0 2018 年 6 月 25 日
0.5.0 2018 年 3 月 1 日
0.4.0 2018 年 2 月 24 日
0.3.0 2017 年 9 月 6 日
0.1.1 2017 年 8 月 23 日

⚠️ 已报告问题

#2426Rust 模式

Download history 31/week @ 2024-03-11 23/week @ 2024-03-18 8/week @ 2024-03-25 40/week @ 2024-04-01 23/week @ 2024-04-08 35/week @ 2024-04-15 42/week @ 2024-04-22 33/week @ 2024-04-29 3/week @ 2024-05-06 7/week @ 2024-05-13 34/week @ 2024-05-20 30/week @ 2024-05-27 31/week @ 2024-06-03 47/week @ 2024-06-10 14/week @ 2024-06-17 46/week @ 2024-06-24

141 每月下载量

MIT 许可证

17KB
191

Endian 特性

Crate Docs Gitlab CI Status Travis CI Status

这个包提供了一个特性 Endian,它要求四种方法来在大小端顺序之间转换具有多字节表示的原始类型。除了声明特性之外,这个库还在 Rust 的原始类型(boolchar{i,u}}}f32f64)以及所有切片 &mut [Endian] 上实现它。

这个包还提供了一个自定义 derive 宏,可以通过 #[macro_use] 使用。

这个库的主要目的是帮助在机器边界之间直接二进制序列化 Rust 类型。这不是在网络上或文件系统中移动数据的健壮方法,但可以作为构建更强大的二进制序列化过程的基线。请注意,常见的传输方法还需要实现转换到/从字节数组的转换,这目前超出了这个库的范围。

用法

最低 Rust 版本:1.20

在您的 Cargo.toml 中需要这个包(endian_trait),并使用 #[macro_use] 标记以访问自定义 derive 宏。

[dependencies]
endian_trait = "0.5"

在您的包根目录中导入它们

#[macro_use]
extern crate endian_trait;

然后使用 Endian 特性来翻转字节。

use endian_trait::Endian;

#[derive(Endian)]
struct Foo {
    bar: i32,
    baz: f64,
}

#[derive(Endian)]
struct Quux {
    f: Foo,
    g: bool,
}

let q = Quux {
    f: Foo {
        bar: 42,
        baz: 6.283185,
    },
    g: true,
}.to_be();

let q2: Quux = q.from_be();

有用的 ... 用法

字节序转换会破坏数据的实用性,在某些情况下(浮点数、字符)甚至会破坏数据的有效性。一旦数据从本地字节序转换,它就再也不能用作任何东西,而只能作为没有进一步意义的字节序列。同样,从一种顺序到本地字节序的转换,只有在已知字节序列形状正确的情况下才有用。

在我的使用这个功能的项目中,我使用了以下二进制序列化/反序列化的工作流程:

#[derive(Endian)]
struct Foo {
    //  fields
}
impl From<[u8; N]> for Foo {
    fn from(src: [u8; N]) -> Self {
        //  move fields into a byte array
    }
}
impl Into<[u8; N]> for Foo {
    fn into(self) -> [u8; N] {
        //  pull segments of the array into fields
    }
}

let f: Foo = make_a_foo();
let fbytes: [u8; N] = f.to_be().into();

let raw_foo: [u8; N] = read_from_network();
let build_foo: Foo = Foo::from(raw_foo).from_be();

请记住,一旦数据被转换为传输字节序,它就不能再被视为任何东西,而只能是一组字节。转换字符或浮点数几乎总是会导致一个无效的位模式,这种无效性将一直持续到在另一端将其转换回本地顺序。用于二进制序列化/反序列化的 FromInto 实现应该只是类型转换和字节移动,因为它们很可能处理的是宽度正确但逻辑上无效的数据。

您也可以将字节序转换移入 From/Into 方法,但我个人更喜欢保持它们解耦。

据我所知,没有其他理由使用这个特性。

额外功能

您可以使用 --features arrays 编译选项来在数组 [T: Endian; N] 上实现 Endian,其中 N 的范围是 0 ≤ N ≤ 256。没错;我支持比标准库多八倍的数组。

我们真的需要类型级别的整数。

在夜间构建(RFC #1504问题 #35118),您可以使用 --features e128 编译选项来在 i128u128 上实现 Endian。

在您的 Cargo.toml 中,将原始对 endian_trait 的依赖项替换为:

[dependencies.endian_trait]
version = 0.5
features = [
    "arrays",
    "e128", # currently only available on nightly, issue #35118, RFC #1504
]

依赖项

~2MB
~47K SLoC