Tracker - track changes to structs efficiently

Rust Tracker on crates.io Tracker on docs.rs

Tracker is a small crate that allows you to track changes to struct fields.

It implements the following methods for your struct fields:

To check for changes you can call var_name.changed(StructName::field_name()) and it will return a bool.

To reset all previous changes you can call var_name.reset().

How it works

Let's have a look at a small example.

```rust

[tracker::track]

struct Test { x: u8, y: u64, }

fn main() { let mut t = Test { x: 0, y: 0, // the macro generates a new variable called // "tracker" that stores the changes tracker: 0, };

t.set_x(42);
// let's check whether the change was detected
assert!(t.changed(Test::x()));

// reset t so we don't track old changes
t.reset();

t.set_x(42);
// same value so no change
assert!(!t.changed(Test::x()));

} ```

What happens behind the scenes when you call set_x() is that a bitflag is set in the tracker field of your struct:

y x tracker: u8 = | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | set_x(42) -> | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | reset() -> | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |

As you can see this works pretty efficient. The macro expansion looks like this:

rust impl Test { pub fn get_x(&self) -> &u8 { &self.x } pub fn get_mut_x(&mut self) -> &mut u8 { self.tracker |= Self::x(); &mut self.x } pub fn update_x<F: Fn(&mut u8)>(&mut self, f: F) { self.tracker |= Self::x(); f(&mut self.x); } pub const fn x() -> u8 { 1 << 0usize } pub fn set_x(&mut self, value: u8) { if self.x != value { self.tracker |= Self::x(); } self.x = value; } }

Further attributes

```rust

[tracker::track]

struct Test { #[tracker::donottrack] a: u8, #[donottrack] b: u8, #[tracker::noeq] c: u8, #[noeq] d: u8, } ```

You can mark fields as