I'm trying to create a sort-of observer pattern in rust and I am getting a compile error that is basically telling me (I think) it doesn't know the size of a function param at runtime. I didn't realize the size of a function pointer was unknown at runtime. More importantly, I don't have a clue how to tell it the size
christianb@christianb-mac debug % cargo build
Compiling pyrsia-blockchain v0.1.0 (/Users/christianb/dev/jfrog/rusty-brown)
error[E0277]: the size for values of type `(dyn Fn(Foo) -> Result<(), (dyn std::error::Error + 'static)> + 'static)` cannot be known at compilation time
--> src/main.rs:45:16
|
45 | observers: HashMap<&'a Foo, OnFooDone>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Fn(Foo) -> Result<(), (dyn std::error::Error + 'static)> + 'static)`
note: required by a bound in `HashMap`
error[E0277]: the size for values of type `(dyn std::error::Error + 'static)` cannot be known at compilation time
--> src/main.rs:45:16
|
45 | observers: HashMap<&'a Foo, OnFooDone>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn std::error::Error + 'static)`
note: required by a bound in `Result`
error[E0277]: the size for values of type `(dyn std::error::Error + 'static)` cannot be known at compilation time
--> src/main.rs:49:54
|
49 | pub fn submit_foo(&mut self, foo: &Foo, on_done: OnFooDone) -> &Self {
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn std::error::Error + 'static)`
note: required by a bound in `Result`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `pyrsia-blockchain` due to 3 previous errors
use std::collections::HashMap;
use std::error::Error;
fn main() {
let mut holder = Holder {
observers: HashMap::new()
};
let foo0 = Foo {
id: 0,
stuff: **"hello",
};
let foo1 = Foo {
id: 1,
stuff: **"world",
};
let mut foo2 = Foo {
id: 2,
stuff: **"bob",
};
let mut magic_num = 5;
let mut closure = |foo| {
println!("Slow");
magic_num += foo.id;
foo.id
};
holder.submit_foo(&foo0, |f| {
println!("received foo {}", f.id)?
});
holder.submit_foo(&foo1, |f| {
println!("received foo2 {}", f.id)?
});
holder.submit_foo(&foo2, closure);
holder.notify_all();
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Foo {
id: u64,
stuff: str,
}
type OnFooDone = dyn Fn(Foo) -> Result<(),dyn Error>;
pub struct Holder<'a> {
observers: HashMap<&'a Foo, OnFooDone>,
}
impl Holder<'_> {
pub fn submit_foo(&mut self, foo: &Foo, on_done: OnFooDone) -> &Self {
self.observers.insert(foo, on_done);
self
}
pub fn notify_all(self) -> Self {
self.observers.iter().for_each(|k, f| f(k));
self
}
}