6个版本
新版本 0.2.4 | 2024年8月23日 |
---|---|
0.2.3 | 2024年8月23日 |
0.1.0 | 2024年8月19日 |
#322 in 编码
每月326次下载
70KB
1K SLoC
marshal-rs
marshal-rs
是Ruby语言Marshal
的Rust实现。
该项目本质上只是@savannstm/marshal,用Rust重写的。它能够以 🔥 闪电般的速度 加载来自Ruby Marshal文件的输出,以及 🔥 闪电般的速度 将其转回Marshal格式。
安装
cargo添加marshal-rs
快速概览
这个crate有两个主要功能:load()
和dump()
。
load()
接受一个&[u8]
,它由Marshal数据字节(可以使用std::fs::read()
读取)组成,作为其唯一参数,并输出serde_json::Value
(如果启用了sonic
功能,则为sonic_rs::Value
)。
dump()
则接受Value
作为其唯一参数,并将其反序列化为Vec<u8>
Marshal字节流。它不保留字符串的初始编码,将所有字符串都写入UTF-8编码。
注意
marshal-rs
**不会**写入对象链接。这意味着输出文件的大小可能比最初更大。否则,它对输出文件没有影响。我**非常**需要帮助写入对象链接。如果你是Ruby/Rust资深人员,并且对Marshal格式非常精通,请考虑向这个仓库提交一个pull request或其他什么。
如果使用表格将Ruby数据序列化为JSON
Ruby对象 | 序列化为JSON |
---|---|
nil |
null |
1337 (整数) |
1337 |
36893488147419103232 (大整数) |
{ __type: "bigint", value: "36893488147419103232" } (普通对象) |
13.37 (浮点数) |
13.37 |
"ligma" (字符串) |
"ligma" |
:ligma (符号) |
"__symbol__ligma" |
/lgma/i (正则表达式) |
{ "__type": "regexp", "expression": "lgma", flags: "i" } (普通对象) |
[] (数组) |
[] |
{} (哈希) |
{} (普通对象) |
Object.new (包括结构体、模块等) |
{ "__class": "__symbol__Object", "__type": "object" } (普通对象) |
字符串
默认情况下,包含编码实例变量的 Ruby 字符串被序列化为 JSON 字符串,而不包含实例变量的字符串被序列化为 { __type: "bytes", data: [...] }
对象。
此行为可以通过 load
函数的 string_mode
参数进行控制。
StringMode::UTF8
尝试将没有实例变量的数组转换为字符串,如果数组是有效的 UTF8,则生成字符串,否则生成对象。
StringMode::Binary
将所有字符串转换为对象。
对象和符号
对于无法在 JSON 中序列化的对象(如对象和符号),marshal-rs
使用将它们字符串化并添加前缀和属性的方法。它将符号字符串化并在其前面添加 __symbol__
前缀,并将对象的类和类型分别序列化为 __class
键和 __type
键。
哈希键
对于哈希键,在Ruby中可以使用Integer
、Float
、Object
等表示,marshal-rs
尝试通过在字符串化键前添加其类型前缀来保留键类型。例如,Ruby的{1 => nil}
哈希将被转换为{"__integer__1": null}
对象。
实例变量
实例变量始终以字符串形式解码,并带有__symbol__
前缀。您可以使用instance_var_prefix
参数在load()
和dump()
中管理实例变量的前缀。传递的字符串将替换“@”实例变量的前缀。
不安全代码
此代码在load()函数中多次使用UnsafeCell和unsafe块。然而,在当前实现中,这段不安全代码永远不会引起任何数据竞争或不稳定。
快速示例
use std::fs::read;
use marshal_rs::load::load;
use marshal_rs::dump::dump;
fn main() {
// Read marshal data
let marshal_data: Vec<u8> = read("./marshal_file.marshal").unwrap();
// Serializing to json
// load() takes a &[u8] as argument, so bytes Vec must be borrowed
let serialized_to_json: serde_json::Value = load(&marshal_data, None, None);
// Here you may std::fs::write() serialized JSON to file
// Serializing back to marshal
// dump() requires owned Value as argument
let serialized_to_marshal: Vec<u8> = dump(serialized_to_json, None);
// Here you may std::fs::write() serialized Marshal data to file
}
MSRV
最低支持的Rust版本是1.63.0。
参考
许可证
本项目采用WTFPL许可。
依赖关系
~4–11MB
~171K SLoC