I have an observable collection and an observer. I want the observer to be a trait implementation of trait Observer
. The observable object should be able to not
I wrote this answer if you are still interested about it:
I tried this way, and it worked fine with me, it is as simple as:
struct
Listeners
,Extensions
,Emitter
option to the Extensions
by execution Self::Fn
The same code I used in the playground is below, I just solved it in the rust forum:
// 1. Define your object
//#[derive(Debug)]
pub struct Counter {
count: i32,
}
// 2. (Optional), if do not want to use `#[derive(Debug)]`
// you can define your own debug/release format
impl std::fmt::Debug for Counter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Counter `count` is: {}", self.count)
}
}
// 3. Define your Listeners trait
trait EventListener {
fn on_squared() {
println!("Counter squared")
}
fn on_increased(amount: i32) {
println!("Counter increased by {}", amount)
}
fn on_decreased(self, amount: i32);
}
// 4. Implement your Listeners trait to your object
impl EventListener for Counter {
fn on_decreased(self, amount: i32) {
println!("Counter reduced from {} to {}", &self.count, &self.count - amount)
}
}
// 5. (Recommended), Define your standard functions/Extensions/Emitters
// trait signatures
trait EventEmitter {
fn square(&mut self);
fn increase(&mut self, amount: i32);
fn decrease(&mut self, amount: i32);
fn change_by(&mut self, amount: i32);
}
// 6. Implement your standard functions/Extensions/Emitters trait to your object
impl EventEmitter for Counter {
fn square(&mut self) {
self.count = self.count.pow(2);
Self::on_squared(); // This is Event Emitter, calling the Listner
}
fn increase(&mut self, amount: i32) {
self.count = self.count + amount;
Self::on_increased(amount); // This is Event Emitter, calling the Listner
}
fn decrease(&mut self, amount: i32) {
let initial_value = self.count;
self.count = self.count - amount;
Self::on_decreased(Self {count: initial_value}, amount); // This is Event Emitter, calling the Listner
}
fn change_by(&mut self, amount: i32) {
let initial_value = self.count;
self.count = self.count + amount;
match amount {
x if x > 0 => Self::on_increased(amount), // This is Event Emitter, calling the Listner
x if x < 0 => Self::on_decreased(Self {count: initial_value}, // This is Event Emitter, calling the Listneramount.abs()),
_ => println!("No changes")
}
}
}
// 7. Build your main function
fn main() {
let mut x = Counter { count: 5 };
println!("Counter started at: {:#?}", x.count);
x.square(); // Call the extension, which will automatically trigger the listner
println!("{:?}", x);
x.increase(3);
println!("{:?}", x);
x.decrease(2);
println!("{:?}", x);
x.change_by(-1);
println!("{:?}", x);
}
And got the below output:
Counter started at: 5
Counter squared
Counter `count` is: 25
Counter increased by 3
Counter `count` is: 28
Counter reduced from 28 to 26
Counter `count` is: 26
Counter reduced from 26 to 25
Counter `count` is: 25