Observable primitives for rust, inspired by Svelte's Stores.
This crate includes a limited set of observable/reactive primitives. The design and implementation is inspired by Svelte's Store contract. Since Observables are based on simple traits, users could also implement their own versions of it.
This crate is useful if you want to work with observable values. A good example are UI-Projects (e.g. with GTK).
cargo add --git https://github.com/MoritzRS/stores-rs --tag v0.1.0
An event can be used to trigger callbacks. It holds no values.
use stores::{Emitter, Event};
fn main() {
let event = Event::new();
let unsubscribe = event.listen(|| {
println!("Event triggered");
});
event.dispatch(); // "Event triggered"
event.dispatch(); // "Event triggered"
unsubscribe();
event.dispatch(); // Nothing
}
An observable is the most basic primitive in this crate. You can read and write values and subscribe to changes.
use stores::{Readable, Writable, Observable};
fn main() {
let my_number = Observable::new(0);
let unsubscribe = my_number.subscribe(|value| {
println!("My number is: {}", value);
}); // "My number is: 0"
my_number.set(1); // "My number is: 1"
my_number.set(2); // "My number is: 2"
my_number.update(|value| value * 10); // "My number is: 20"
unsubscribe();
my_number.set(30); // Nothing
}
A derived an read only observable that computes its value from its dependencies. You can read its value and subscribe to changes.
use stores::{Readable, Writable, Observable, Derived, derived};
fn main() {
let a = Observable::new(1);
let b = Observable::new(2);
// Manual Creation
let sum = Derived::new(&[a.clone(), b.clone()], {
let a = a.clone();
let b = b.clone();
move || a.get() * b.get()
});
// Macro based Creation
let sum = derive!([a, b] => move || a.get() * b.get());
}
A deduped behaves like an observable, but only notifies its subscribers when its value has actually changed. It can either be standalone or wrap other observables. When it wraps another writable observable, it propagates changes to the original.
use stores::{Readable, Writable, Observable, Deduped};
fn main() {
let my_number = Observable::new(0);
let deduped = Deduped::from(my_number.clone());
let _ = deduped.subscribe(|value| {
println!("Value is {}", value);
}); // "Value is 0"
my_number.set(1); // "Value is 1"
my_number.set(2); // "Value is 2"
my_number.set(2); // Nothing
}
This is one of my first rust projects. I developed it just because I needed for another project. Although I am quite satisfied with the result, breaking changes may occur when my projects demand it.
MIT © Moritz R. Schulz