#erlang #elixir #serde #object

erlang-term

将 Erlang 外部项格式转换为 Rust 对象的库,不使用 erlang NIFs

8 个版本 (2 个稳定版本)

1.1.0 2023年3月25日
1.0.0 2022年8月5日
0.2.4 2022年8月3日
0.2.3 2022年3月4日
0.1.1 2020年5月29日

#2146 in 解析器实现

Download history 27/week @ 2024-03-27 25/week @ 2024-04-03

每月下载量96

Unlicense

135KB
3.5K SLoC

erlang-term

将 Erlang 外部项格式转换为 Rust 对象的库,不使用 erlang NIFs。

安装

[dependencies]
erlang-term = "1.1.0"

使用方法

elixir -e ":erlang.term_to_binary([1,2,3,4]) |> IO.inspect()" | sed -e 's/<</[/g' | sed -e 's/>>/]/g'

复制到 rust

use erlang_term::Term;

let input = &[131, 107, 0, 4, 1, 2, 3, 4];
let term = Term::from_bytes(input);
assert_eq!(Ok(Term::Charlist([1, 2, 3, 4].to_vec())), term);

如果您想对外部项格式有更多控制

use erlang_term::RawTerm;

let input = &[131, 107, 0, 4, 1, 2, 3, 4];

let term = RawTerm::from_bytes(input);
assert_eq!(Ok(RawTerm::String([1, 2, 3, 4].to_vec())), term);

Term 枚举更像是您在 elixir 中找到的。 RawTerm 枚举的命名来自外部项格式规范。

这在上面示例中已经很明显。在 Erlang 中,字符串只是一个字符列表,而在 Elixir 中这被称为 Charlist。

在这个库中,我试图分离逻辑和转换,因此在 RawTerm 中只有二进制和 Rust 枚举之间的转换,而在 Term 中有逻辑将它们转换为可用的接口。因此 RawTerm 到二进制是一对一和满射的。但是从 TermRawTerm 将会丢失信息。

特性

有一个可选的 serde 特性。

erlang-term = {version = "1.1.0", features = ["serde_impl"]}

有一个可选的 zlib 特性,允许压缩 etf。在 Elixir

:erlang.term_to_binary(t, [:compressed])
# or
:erlang.term_to_binary(t, compressed: 6)
erlang-term = {version = "1.1.0", features = ["zlib"]}

更多示例

use erlang_term::RawTerm;
use std::iter::FromIterator;

let map = RawTerm::Map(vec![
    (RawTerm::SmallAtom(String::from("test")), RawTerm::SmallTuple(vec![RawTerm::SmallAtom(String::from("ok")), RawTerm::SmallInt(15)])),
    (RawTerm::SmallAtom(String::from("another_key")), RawTerm::Binary(b"this is a string".to_vec())),
    (RawTerm::SmallAtom(String::from("number")), RawTerm::Float(3.1415.into())),
]);

let binary = vec![
    131, 116, 0, 0, 0, 3, 119, 4, 116, 101, 115, 116, 104, 2, 119, 2, 111, 107, 97, 15, 119, 11, 97, 110, 111, 116, 104, 101, 114, 95, 107, 101, 121, 109, 0, 0, 0, 16, 116, 104, 105, 115, 32, 105, 115, 32, 97, 32, 115, 116, 114, 105, 110, 103, 119, 6, 110, 117, 109, 98, 101, 114, 70, 64, 9, 33, 202, 192, 131, 18, 111
];

assert_eq!(map.to_bytes(), binary);

用例

  • 从存储的 etf 文件中过滤出非数据(如引用和函数)

  • 将存储的 etf 文件转换为 json

参见 filter 示例

许可证:Unlicense

依赖

~2.6–3.5MB
~75K SLoC