Reactive change notifications using futures.
The ChangeTracker<T> type wraps an owned value T. Changes to T are
done within a function or closure implementing FnOnce(&mut T). When this
returns, any changes are sent to listeners using a futures::Stream.
In slightly more detail, create a ChangeTracker<T> with
ChangeTracker::new(value: T). This
will take ownership of the value of type T. You can then create a
futures::Stream (with
get_changes()) that emits
a tuple (old_value, new_value) of type (T, T) upon every change to the
owned value. The value can be changed with the
modify() method of
ChangeTracker and read using the as_ref() method from the AsRef trait.
In this example, the functionality of ChangeTracker is shown.
```rust use futures::stream::StreamExt;
// Wrap an integer with ChangeTracker
let mut changetracker = asyncchange_tracker::ChangeTracker::new( 123 );
// Create an receiver that fires when the value changes. The channel size // is 1, meaning at most one change can be buffered before backpressure // is applied. let rx = changetracker.getchanges(1);
// In this example take a single change and check that the old and new value // are correct. let rxprinter = rx.take(1).foreach(|(oldvalue, newvalue)| { asserteq!( oldvalue, 123); asserteq!( newvalue, 124); futures::future::ready(()) });
// Now, check and then change the value. changetracker.modify(|mutrefvalue| { asserteq!(*mutrefvalue, 123); *mutrefvalue += 1; });
// Wait until the stream is done. In this example, the stream ends due to
// the use of .take(1) prior to for_each above. In normal usage,
// typically the stream would finish for a different reason.
futures::executor::blockon(rxprinter);
// Finally, check that the final value is as expected. assert!(*changetracker.asref() == 124); ```
To test, you need the thread-pool feature for the futures create:
cargo test --features "futures/thread-pool"
License: MIT/Apache-2.0