Last active
March 15, 2020 17:29
-
-
Save MartinKavik/36a96f28b9bad76d6cb7141946f5f716 to your computer and use it in GitHub Desktop.
Return `Msg` or `()` in handlers. | Runtime panics | Stable Rust
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::any::{Any, TypeId}; | |
#[derive(Debug)] | |
enum Msg { | |
Increment, | |
} | |
fn main() { | |
let handlers: Vec<Handler<Msg>> = vec![ | |
Handler::new(|| Msg::Increment), | |
Handler::new(|| println!("Look, no msg!")), | |
//Handler::new(|| 123), | |
]; | |
for handler in handlers { | |
let msg = (handler.callback)(); | |
println!("Msg: {:?}", msg); | |
} | |
} | |
struct Handler<Ms> { | |
callback: Box<dyn Fn() -> Option<Ms>>, | |
} | |
impl<Ms: 'static> Handler<Ms> { | |
fn new<T: 'static>(callback: impl FnOnce() -> T + Clone + 'static) -> Self { | |
let t_type = TypeId::of::<T>(); | |
if t_type != TypeId::of::<Ms>() && t_type != TypeId::of::<()>() { | |
panic!("Handler can return only Msg or ()!"); | |
} | |
let callback = move || { | |
let output = &mut Some(callback.clone()()) as &mut dyn Any; | |
output | |
.downcast_mut::<Option<Ms>>() | |
.and_then(Option::take) | |
}; | |
Self { | |
callback: Box::new(callback), | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can be run in https://play.rust-lang.org/