Hi,
I am struggling to get ownership and lifetimes correct when trying to implement a 'chain of handlers'. I have implementations of handlers abstracted by a trait Handler
, which I can add to a handler chain. The chain should then process a data element by applying each of its handlers to the data element. The handlers need to collect statistics during processing and I need to access this data after processing all elements. The closest to a working solution I was able to come up with is the code below. It still doesn't compile (see line commented with 'cannot borrow'). I've tried out many variants of this solution but either struggle with ownership or with lifetime annotations. Any help is appreciated.
trait Handler {
fn handle(&mut self, data: u32);
}
struct HandlerA {
field: u32,
}
impl Handler for HandlerA {
fn handle(&mut self, data: u32) {
if data % 2 == 0 { self.field += 1 };
}
}
struct HandlerB {
field: u32,
}
impl Handler for HandlerB {
fn handle(&mut self, data: u32) {
if data % 2 == 1 { self.field += 1 };
}
}
struct HandlerChain<'a> {
pub handlers: Vec<&'a dyn Handler>,
}
impl<'a> HandlerChain<'a> {
fn new() -> HandlerChain<'a> {
HandlerChain {
handlers: vec![],
}
}
fn append(&mut self, s: &'a dyn Handler) -> &mut Self {
self.handlers.push(s);
self
}
fn run_handlers(&mut self, data: u32) {
for h in &mut self.handlers {
h.handle(data); // cannot borrow `**h` as mutable
}
}
}
fn main() {
let one: HandlerA = HandlerA { field: 0 };
let another: HandlerB = HandlerB { field: 0 };
let mut chain: HandlerChain = HandlerChain::new();
chain
.append(&one)
.append(&another)
;
for u in 1..5 {
chain.run_handlers(u);
}
assert_eq!(one.field, 2);
}