#bibtex #序列化 #serde

bin+lib serde_bibtex

BibTex (反)序列化文件格式

8 个版本

0.3.1 2024年6月3日
0.3.0 2024年6月3日
0.2.4 2024年1月25日
0.1.0 2024年1月17日

#1320解析器实现

MIT/Apache

175KB
3.5K SLoC

Current crates.io release Documentation

警告

此包正在积极开发中,并且公共 API 可能会在每个小版本更改中发生重大变化。反序列化 API 相对稳定,但序列化尚未实现,并且一些公开的内部状态可能会更改。在此稳定之前,请自行承担风险!

Serde bibtex

一个提供 Rust 库,用于对 .bib 文件进行(反)序列化。实现尽可能少地具有意见,功能丰富,方便其他库或二进制文件的下层消费。

有关示例和功能的详细文档,请访问 文档

反序列化器

以下是主要功能。

灵活

  • 结构化:使用自动 @string 宏展开和其他便利功能将数据读取到 Rust 类型中。
  • 非结构化:不展开宏或不收集字段值以保留原始 BibTeX 的结构。
  • 从字节反序列化,以延迟 UTF-8 转换,甚至可以传递原始字节。
  • 容错 Iterator API 允许跳过格式错误的条目。

明确的语法,无歧义

快速

  • 低开销的手动解析器实现(请参阅 基准测试)。
  • 零复制反序列化。
  • 选择性捕获内容(请参阅 基准测试 以比较速度差异)

序列化器

待办事项:尚未实现

与其他包的比较

typst/biblatex

我们不尝试解释.bib文件中条目的内容,而是将其解释推迟到下游使用。另一方面,biblatex旨在支持typst,它需要解释字段内容(例如,解析字段值中的$math$)。从这个意义上说,我们的实现可能更接近于biblatex::RawBibliography的入口点,但具有读取任何实现适当Deserialize类型的巨大额外灵活性。

charlesvdv/nom-bibtex

这个crate中的功能基本上取代了nom-bibtex。我们不支持nom-bibtex的唯一功能是捕获不在@comment条目中明确包含的注释。

typho/bibparser

这个crate中的功能基本上取代了bibparser

基准测试

基准测试代码可以在benches/compare.rs中找到。使用的参考文献文件是assets/tugboat.bib,这是biber使用的测试数据的一部分。它是一个2.64 MB、73,993行的.bib文件。

  1. ignore:使用serde::de::IgnoredAny进行反序列化以解析文件,但忽略内容。
  2. struct:使用一个结构体进行反序列化,该结构体捕获了assets/tugboat.bib(总计15个字段)中存在的所有字段,展开宏并折叠字段值。
  3. borrow:反序列化到一个完全借用型的Rust类型,它捕获了文件中的所有数据,但不展开宏或折叠字段值。
  4. biblatex:使用biblatex::RawBibliography::parse进行解析(与borrow最相似)。
  5. copy:反序列化到一个具有宏展开、字段值折叠和适当的情况不敏感比较的拥有型Rust类型。
  6. nom-bibtex:使用nom-bibtex::Bibtex::parse进行解析(与copy最相似)。

基准测试是在Intel(R) Core(TM) i7-9750H CPU @ 2.60 GHz (2019 MacBook Pro)上进行的。

基准测试 因子 运行时间 吞吐量
ignore 0.18x [3.3923毫秒3.3987毫秒3.4058毫秒] 660 MB/s
struct 0.67x [8.5496毫秒8.7481毫秒8.9924毫秒] 300 MB/s
borrow 1.0x [12.932毫秒12.962毫秒12.992毫秒] 200 MB/s
biblatex 1.3x [16.184毫秒16.224毫秒16.266毫秒] 160 MB/s
copy 1.7x [21.455毫秒21.690毫秒21.935毫秒] 120 MB/s
nom-bibtex 5.5x [71.607毫秒71.912毫秒72.343毫秒] 40 MB/s

由于bibparser crate无法解析输入文件,它不包括在这个基准测试中。

安全性

当我们可以保证其他原因使得字符串切片位于有效的codepoint时,这个crate使用一些unsafe进行字符串转换。

依赖关系

~0.3–1.1MB
~21K SLoC