Last active
December 21, 2021 19:34
-
-
Save apowers313/3cdcc808bd038069839f573e482ce333 to your computer and use it in GitHub Desktop.
Rust method as function pointer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::HashMap; | |
macro_rules! handler { | |
($kernel:expr, $method:ident) => { | |
Box::new(|x| $kernel.$method(x)) | |
}; | |
} | |
fn main() { | |
let k = Kernel::new(); | |
k.recv("test".to_string(), "this is a test of the emergency broadcast system".to_string()); | |
} | |
struct Msg{ | |
msg_type: String, | |
msg: String | |
} | |
struct Kernel<'env> { | |
handlers: HandlerCollection<'env> | |
} | |
impl Kernel<'_> { | |
fn new() -> Self { | |
let s = Self { | |
handlers: HandlerCollection::new() | |
}; | |
s.handlers.add_handler(String::from("test"), handler!(s, test_handler)); | |
s | |
} | |
fn recv(&self, msg_type: String, msg: String) { | |
self.handlers.call(msg_type, msg) | |
} | |
pub fn test_handler(&self, msg: String) -> Result<(), &'static str> { | |
println!("test msg: {}", msg); | |
Ok(()) | |
} | |
} | |
type HandlerFn<'env> = Box<dyn 'env + Fn(String) -> Result<(), &'static str>>; | |
struct HandlerCollection<'env> { | |
collection: HashMap<String, HandlerFn<'env>>, | |
} | |
impl HandlerCollection<'_> { | |
fn new() -> Self { | |
let mut s = Self { | |
collection: HashMap::new(), | |
}; | |
s | |
} | |
fn add_handler(&mut self, name: String, handler: HandlerFn) { | |
// cannot infer an appropriate lifetime due to conflicting requirements | |
self.collection.insert(name, handler); | |
} | |
fn call(&self, msg_type: String, msg: String) { | |
let handler = match self.collection.get(&msg_type) { | |
Some(x) => x, | |
None => { | |
println!("no message handler found for message type: '{}'", msg_type); | |
return; | |
} | |
}; | |
match handler(msg) { | |
Ok(()) => return, | |
Err(e) => println!("error while handling {}: {}", msg_type, e), | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment