Skip to content

Commit 2554e7e

Browse files
committed
Changelog + README
1 parent ec3a282 commit 2554e7e

File tree

3 files changed

+71
-9
lines changed

3 files changed

+71
-9
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## Unreleased
22

3+
- Add `#[cache_diff(custom = <function>)]` to containers (structs) to allow for customizing + deriving diffs. ()
4+
- Add: Allow annotating ignored fields with `#[cache_diff(ignore = "<reason>")]`. Using `ignore = "custom"` requires the container (struct) to implement `custom = <function>`. ()
5+
6+
## 1.0.1
7+
38
- Fix: Multiple `#[derive(CachDiff)]` calls in the same file now work (https://github.com/heroku-buildpacks/cache_diff/pull/4)
49

510
## 1.0.0

cache_diff/README.md

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@ When it returns an empty list, the two structs are identical.
2626

2727
You can manually implement the trait, or you can use the `#[derive(CacheDiff)]` macro to automatically generate the implementation.
2828

29-
Attributes are:
29+
Top level struct configuration (Container attributes):
3030

31-
- `cache_diff(rename = "<new name>")` Specify custom name for the field
32-
- `cache_diff(ignore)` Ignores the given field
33-
- `cache_diff(display = <function>)` Specify a function to call to display the field
31+
- `#[cache_diff(custom = <function>)]` Specify a function that receives references to both current and old values and returns a Vec of strings if there are any differences. This function is only called once. It can be in combination with `#[cache_diff(custom)]` on fields to combine multiple related fields into one diff (for example OS distribution and version) or to split apart a monolithic field into multiple differences (for example an "inventory" struct that contains a version and CPU architecture information).
32+
33+
Attributes for fields are:
34+
35+
- `#[cache_diff(rename = "<new name>")]` Specify custom name for the field
36+
- `#[cache_diff(ignore)]` or `#[cache_diff(ignore = "<reason>")]` Ignores the given field with an optional comment string.
37+
If the field is ignored because you're using a custom diff function (see container attributes) you can use
38+
`cache_diff(ignore = "custom")` which will check that the container implements a custom function.
3439

3540
### Why
3641

@@ -189,6 +194,58 @@ let diff = now.diff(&Metadata { version: NoDisplay("3.3.0".to_string())});
189194
assert_eq!(diff.join(" "), "version (`custom 3.3.0` to `custom 3.4.0`)");
190195
```
191196

197+
### Customize one or more field differences
198+
199+
You can provide a custom implementation for a diffing a subset of fields without having to roll your own implementation.
200+
201+
#### Custom logic for one field example
202+
203+
Here's an example where someone wants to bust the cache after N cache calls. Everything else other than `cache_usage_count` can be derived. If you want to keep the existing derived difference checks, but add on a custom one you can do it like this:
204+
205+
```rust
206+
use cache_diff::CacheDiff;
207+
const MAX: f32 = 200.0;
208+
209+
#[derive(Debug, CacheDiff)]
210+
#[cache_diff(custom = diff_cache_usage_count)]
211+
pub(crate) struct Metadata {
212+
#[cache_diff(ignore = "custom")]
213+
cache_usage_count: f32,
214+
215+
binary_version: String,
216+
target_arch: String,
217+
os_distribution: String,
218+
os_version: String,
219+
}
220+
221+
fn diff_cache_usage_count(_old: &Metadata, now: &Metadata) -> Vec<String> {
222+
let Metadata {
223+
cache_usage_count,
224+
binary_version: _,
225+
target_arch: _,
226+
os_distribution: _,
227+
os_version: _,
228+
} = now;
229+
230+
if cache_usage_count > &MAX {
231+
vec![format!("Cache count ({}) exceeded limit {MAX}", cache_usage_count)]
232+
} else {
233+
Vec::new()
234+
}
235+
}
236+
```
237+
238+
In this example, four fields are derived automatically, saving us time, while one field is custom
239+
using the `#[cache_diff(custom = diff_cache_usage_count)]` attribute on the struct. This tells
240+
[CacheDiff] to call this function and pass in the old and current values. It expects a vector
241+
with some strings if there is a difference and an empty vector if there are none.
242+
243+
Don't forget to "ignore" any fields you're implementing yourself. You can also use this feature to
244+
combine several fields into a single diff output, for example using the previous struct, if
245+
you only wanted to have one output for a combined `os_distribution` and `os_version` in one output
246+
like "OS (ubuntu-22 to ubuntu-24)". Alternatively, you can use <https://github.com/schneems/magic_migrate> to
247+
re-arrange your struct to only have one field with a custom display.
248+
192249
<!-- cargo-rdme end -->
193250

194251
## Releasing

cache_diff/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
//!
1010
//! Top level struct configuration (Container attributes):
1111
//!
12-
//! - `#[cache_diff(custom = <function>)]` Specify a function that receives references to both current and old values and returns a Vec of strings if there are any differences. This function is only called once. It can be in combination with `#[cache_diff(custom)]` on fields to combine multiple related fields into one diff (for example OS distribution and version) or to split apart a monolithic field into multiple differences (for example an "inventory" struct that contains a version and CPU architecture information).
12+
//! - `#[cache_diff(custom = <function>)]` Specify a function that receives references to both current and old values and returns a Vec of strings if there are any differences. This function is only called once. It can be in combination with `#[cache_diff(custom)]` on fields to combine multiple related fields into one diff (for example OS distribution and version) or to split apart a monolithic field into multiple differences (for example an "inventory" struct that contains a version and CPU architecture information).
1313
//!
1414
//! Attributes for fields are:
1515
//!
16-
//! - `#[cache_diff(rename = "<new name>")]` Specify custom name for the field
17-
//! - `#[cache_diff(ignore)]` or `#[cache_diff(ignore = "<reason>")]` Ignores the given field with an optional comment string.
18-
//! If the field is ignored because you're using a custom diff function (see container attributes) you can use
19-
//! `cache_diff(ignore = "custom")` which will check that the container implements a custom function.
16+
//! - `#[cache_diff(rename = "<new name>")]` Specify custom name for the field
17+
//! - `#[cache_diff(ignore)]` or `#[cache_diff(ignore = "<reason>")]` Ignores the given field with an optional comment string.
18+
//! If the field is ignored because you're using a custom diff function (see container attributes) you can use
19+
//! `cache_diff(ignore = "custom")` which will check that the container implements a custom function.
2020
//!
2121
//! ## Why
2222
//!

0 commit comments

Comments
 (0)