Rust序列化库serde-hex的使用:高效实现十六进制编码与解码的serde扩展
serde-hex
Rust crate 用于简便且多功能的十六进制值序列化/反序列化。
概述
serde-hex
crate 围绕 SerHex
trait 构建,可以轻松指定自定义的十六进制序列化/反序列化。一旦实现,SerHex
trait 通过其泛型类型参数进行配置(例如:SerHex<Compact>
用于没有前导零的十六进制值,或 SerHex<StrictPfx>
用于带前导零和 0x
前缀的值)。得益于 Rust 强大的编译器,只有配置实际使用的序列化/反序列化功能部分会被编译。使用 SerHex
最常见的方式是在为类型派生 Serialize
和 Deserialize
trait 时。
SerHex
自动为所有无符号整数类型实现,所有 Strict
变体为 [T;1]
到 [T;64]
的数组实现(当然,其中 T: SerHex
)。我们跳过了长度为零的数组的默认实现,以及有符号整数和浮点数,因为没有特别直观的方式来表示这些值。
这个 crate 提供了许多有用的宏,用于在常见模式上实现 SerHex
。如果没有宏适合你的需求,还提供了一些实用函数,使实现自定义变体尽可能轻松。
注意
如果你只是寻找通用的十六进制转换 trait,请查看广泛使用的 hex
crate。这个 crate 相当专门用于可定制的 serde
互操作,如果你不需要这个功能,应该优先使用 hex
crate 的通用 trait。
许可证
根据以下任一许可证授权:
- Apache License, Version 2.0
- MIT license
由你选择。
贡献
除非你明确声明,否则任何有意提交包含在作品中的贡献,如 Apache-2.0 许可证所定义,应按照上述双重许可,不附加任何额外条款或条件。
内容中提供的示例:
use serde_hex::{SerHex,StrictPfx,CompactPfx};
#[derive(Debug,PartialEq,Eq,Serialize,Deserialize)]
struct Foo {
#[serde(with = "SerHex::<StrictPfx>")]
bar: [u8;4],
#[serde(with = "SerHex::<CompactPfx>")]
bin: u64
}
fn it_works() {
let foo = Foo { bar: [0,1,2,3], bin: 16 };
let ser = serde_json::to_string(&foo).unwrap();
let exp = r#"{"bar":"0x00010203","bin":"0x10"}"#;
assert_eq!(ser,exp);
}
完整示例代码:
// 添加依赖到 Cargo.toml:
// serde-hex = "0.1.0"
// serde = { version = "1.0", features = ["derive"] }
// serde_json = "1.0"
use serde::{Serialize, Deserialize};
use serde_hex::{SerHex, StrictPfx, CompactPfx};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
struct Example {
// 使用 StrictPfx 配置:带前导零和 0x 前缀
#[serde(with = "SerHex::<StrictPfx>")]
strict_field: [u8; 4],
// 使用 CompactPfx 配置:紧凑格式带 0x 前缀
#[serde(with = "SerHex::<CompactPfx>")]
compact_field: u64,
}
fn main() {
// 创建示例结构体实例
let example = Example {
strict_field: [0, 1, 2, 3],
compact_field: 16,
};
// 序列化为 JSON 字符串
let serialized = serde_json::to_string(&example).unwrap();
println!("Serialized: {}", serialized);
// 预期输出:{"strict_field":"0x00010203","compact_field":"0x10"}
let expected = r#"{"strict_field":"0x00010203","compact_field":"0x10"}"#;
assert_eq!(serialized, expected);
// 从 JSON 字符串反序列化
let deserialized: Example = serde_json::from_str(&serialized).unwrap();
println!("Deserialized: {:?}", deserialized);
// 验证反序列化后的数据与原始数据一致
assert_eq!(deserialized, example);
}
serde-hex:Rust中的十六进制编码与解码扩展
概述
serde-hex是一个基于serde的Rust库扩展,专门用于处理十六进制数据的序列化与反序列化。它提供了高效且类型安全的方式,将二进制数据转换为十六进制字符串表示,或从十六进制字符串解析回原始数据。
核心特性
- 支持固定大小数组和Vec<T>的十六进制编码
- 提供紧凑和标准两种输出格式选项
- 完全兼容serde生态系统
- 零成本抽象,高性能处理
安装方法
在Cargo.toml中添加依赖:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde-hex = "0.1"
基本用法示例
1. 结构体序列化
use serde::{Serialize, Deserialize};
use serde_hex::{SerHex, StrictPfx};
#[derive(Serialize, Deserialize)]
struct Transaction {
#[serde(with = "SerHex::<StrictPfx>")]
hash: [u8; 32],
amount: u64,
}
let tx = Transaction {
hash: [0xab; 32],
amount: 1000,
};
// 序列化为JSON
let json = serde_json::to_string(&tx).unwrap();
println!("{}", json);
// 输出: {"hash":"0xababab...","amount":1000}
2. 向量数据编码
use serde_hex::{SerHex, Compact};
#[derive(Serialize, Deserialize)]
struct DataPacket {
#[serde(with = "SerHex::<Compact>")]
payload: Vec<u8>,
}
let packet = DataPacket {
payload: vec![0xDE, 0xAD, 0xBE, 0xEF],
};
let json = serde_json::to_string(&packet).unwrap();
// 输出: {"payload":"deadbeef"}
3. 自定义配置选项
use serde_hex::{SerHex, Strict, prefixed};
#[derive(Serialize)]
struct CustomConfig {
#[serde(with = "SerHex::<Strict>")]
strict_hex: [u8; 4],
#[serde(with = "prefixed")]
prefixed_hex: Vec<u8>,
}
let data = CustomConfig {
strict_hex: [1, 2, 3, 4],
prefixed_hex: vec![0xFF, 0xEE],
};
4. 反序列化示例
use serde::Deserialize;
use serde_hex::SerHex;
#[derive(Deserialize)]
struct Config {
#[serde(with = "SerHex")]
api_key: [u8; 16],
}
let json_data = r#"{"api_key":"00112233445566778899aabbccddeeff"}"#;
let config: Config = serde_json::from_str(json_data).unwrap();
高级配置
serde-hex提供多种配置选项:
Strict
: 严格模式(默认)StrictPfx
: 带前缀的严格模式Compact
: 紧凑模式- 自定义前缀和大小写设置
错误处理
use serde_hex::ParseHexError;
fn process_hex_data(hex_str: &str) -> Result<Vec<u8>, ParseHexError> {
serde_hex::from_hex(hex_str)
}
性能建议
- 对于固定大小数组,使用数组类型而非Vec以获得最佳性能
- 在需要频繁序列化的场景,考虑使用Compact模式减少输出大小
- 批量处理时使用from_hex/to_hex直接函数
这个库特别适合处理加密货币地址、哈希值、二进制配置数据等需要十六进制表示的场景。
完整示例demo
// 完整示例:展示serde-hex的各种用法
use serde::{Serialize, Deserialize};
use serde_json;
use serde_hex::{SerHex, Strict, StrictPfx, Compact, prefixed, from_hex, to_hex};
// 示例1:基本结构体序列化与反序列化
#[derive(Serialize, Deserialize, Debug)]
struct CryptoTransaction {
#[serde(with = "SerHex::<StrictPfx>")] // 使用带前缀的严格模式
transaction_hash: [u8; 32],
#[serde(with = "SerHex::<Compact>")] // 使用紧凑模式
sender_address: Vec<u8>,
amount: u64,
}
// 示例2:配置数据解析
#[derive(Deserialize, Debug)]
struct AppConfig {
#[serde(with = "SerHex::<Strict>")] // 使用严格模式(默认)
secret_key: [u8; 32],
#[serde(with = "prefixed")] // 使用带前缀的模式
api_token: Vec<u8>,
}
// 示例3:自定义错误处理
fn hex_processing_demo() -> Result<(), Box<dyn std::error::Error>> {
// 直接使用from_hex/to_hex函数
let data = vec![0x01, 0x02, 0x03, 0x04];
let hex_string = to_hex::<Compact>(&data)?;
println!("编码后的十六进制: {}", hex_string);
let decoded_data = from_hex(&hex_string)?;
println!("解码后的数据: {:?}", decoded_data);
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 示例1:加密货币交易
let transaction = CryptoTransaction {
transaction_hash: [0xab; 32],
sender_address: vec![0xde, 0xad, 0xbe, 0xef],
amount: 1000000,
};
let json_output = serde_json::to_string(&transaction)?;
println!("交易序列化: {}", json_output);
// 示例2:配置解析
let config_json = r#"
{
"secret_key": "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff",
"api_token": "0xffeeddccbbaa99887766554433221100"
}"#;
let config: AppConfig = serde_json::from_str(config_json)?;
println!("解析的配置: {:?}", config);
// 示例3:直接十六进制处理
hex_processing_demo()?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hex_conversion() {
let original = vec![0x01, 0x02, 0x03, 0x04];
let hex_str = to_hex::<Compact>(&original).unwrap();
assert_eq!(hex_str, "01020304");
let decoded = from_hex(&hex_str).unwrap();
assert_eq!(decoded, original);
}
#[test]
fn test_different_modes() {
let data = vec![0xAB, 0xCD, 0xEF];
// 测试不同模式
let strict = to_hex::<Strict>(&data).unwrap();
let strict_pfx = to_hex::<StrictPfx>(&data).unwrap();
let compact = to_hex::<Compact>(&data).unwrap();
println!("Strict: {}", strict);
println!("StrictPfx: {}", strict_pfx);
println!("Compact: {}", compact);
}
}
这个完整示例展示了serde-hex库的主要功能:
- 结构体的序列化和反序列化,支持不同的十六进制编码模式
- 配置数据的解析和处理
- 直接使用from_hex/to_hex函数进行十六进制转换
- 错误处理和单元测试
示例中包含了严格模式、带前缀模式和紧凑模式的使用,以及如何在不同场景下选择合适的编码方式。