21次发布

0.7.1 2024年4月25日
0.6.3 2024年3月16日
0.5.9 2023年10月30日
0.5.7 2023年5月11日
0.4.1 2022年11月13日

80#difference

Download history 272/week @ 2024-04-21 11/week @ 2024-04-28 1/week @ 2024-05-05 8/week @ 2024-05-19 1/week @ 2024-05-26 9/week @ 2024-06-02 3/week @ 2024-06-09 1/week @ 2024-06-16 145/week @ 2024-06-30 140/week @ 2024-07-28

140 每月下载量
用于 structdiff

MIT 许可证

135KB
3K SLoC

structdiff

一个轻量级的、零依赖的struct差异比较库,允许收集和应用已更改的字段。在一个struct上派生Difference,然后使用StructDiff特质来创建和应用差异。支持使用serdenanoserde对生成的差异类型进行可选序列化,以便于使用。

Crates.io

示例

use structdiff::{Difference, StructDiff};

#[derive(Debug, PartialEq, Clone, Difference)]
struct Example {
    field1: f64,
    #[difference(skip)]
    field2: Vec<i32>,
    #[difference(collection_strategy="unordered_array_like")]
    field3: BTreeSet<usize>,
}

let first = Example {
    field1: 0.0,
    field2: vec![],
    field3: vec![1, 2, 3].into_iter().collect(),
};

let second = Example {
    field1: 3.14,
    field2: vec![1],
    field3: vec![2, 3, 4].into_iter().collect(),
};

let diffs = first.diff(&second);
// diffs is now a Vec of differences between the two instances, 
// with length equal to number of changed/unskipped fields
assert_eq!(diffs.len(), 2);

let diffed = first.apply(diffs);
// diffed is now equal to second, except for skipped field
assert_eq!(diffed.field1, second.field1);
assert_eq!(&diffed.field3, &second.field3);
assert_ne!(diffed, second);

更多示例请查看 集成测试

派生宏属性

  • #[difference(skip)] - 创建差异时不要考虑此字段
  • #[difference(recurse)] - 创建差异时为该字段生成StructDiff
  • #[差异(collection_strategy= {})]
    • "ordered_array_like" - 为实现PartialEq的有序、类似数组的项集合生成最小更改集。(使用levenshtein差异)
    • "unordered_array_like" - 为实现 Hash + Eq 的无序、数组样式的项目集合生成最小的变更集。
    • "unordered_map_like" - 为键实现了 Hash + Eq 的无序、映射样式的集合生成最小的变更集。
  • #[difference(map_equality = {})] - 与 unordered_map_like 一起使用
    • "key_only" - 仅替换键值对,其中键已更改
    • "key_and_value" - 如果键或值已更改,则替换键值对
  • #[difference(setters)] - 为结构体中的所有字段生成设置器(用于结构体)
    • 示例:对于上面使用的 Example 结构体的 field1,将生成一个具有以下签名的函数:set_field1_with_diff(&mut self, value: Option<usize>) -> Option<<Self as StructDiff>::Diff>。当结构体中有许多字段而只需更改单个字段时,这非常有用,因为它可以节省对所有其他字段的比较。
  • #[difference(setter)] - 为此结构体字段生成设置器(用于字段)
  • #[difference(setter_name = {})] - 在生成此字段的设置器时使用此名称代替默认值(用于字段)

可选功能

  • [nanoserde, serde] - 序列化从 Difference 派生的关联类型。允许差异轻松地在网络上发送。
  • debug_diffs - 在生成的差异类型上派生 Debug
  • generated_setters - 启用为结构体字段生成设置器。这些设置器在赋值时自动返回差异,如果字段值已更改。
  • rustc_hash - 使用来自 rustc-hash crate 的(非加密)哈希实现,而不是默认的哈希器。以依赖为代价,为集合生成更快的差异。

开发状态

这正在被积极用于我的个人项目,尽管现在大多数功能都正常工作。接受为更多测试或功能添加的 PR。

依赖项

~200KB