abscissa_core/
runnable.rs1#[doc(hidden)]
4pub use abscissa_derive::Runnable;
5
6pub trait Runnable {
11 fn run(&self);
13}
14
15pub trait RunnableMut {
17 fn run(&mut self);
19}
20
21impl Runnable for Box<dyn Fn()> {
22 fn run(&self) {
23 self();
24 }
25}
26
27impl RunnableMut for Box<dyn FnMut()> {
28 fn run(&mut self) {
29 self();
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use crate::Runnable;
36 use std::sync::Mutex;
37
38 #[allow(dead_code)]
39 #[derive(Runnable)]
40 enum TestEnum {
41 A(VariantA),
42 B(VariantB),
43 }
44
45 #[allow(dead_code)]
46 struct VariantA {}
47
48 impl Runnable for VariantA {
49 fn run(&self) {
50 panic!("don't call this!")
51 }
52 }
53
54 #[derive(Default)]
55 struct VariantB {
56 called: Mutex<bool>,
57 }
58
59 impl VariantB {
60 fn was_called(&self) -> bool {
61 let called = self.called.lock().unwrap();
62 *called
63 }
64 }
65
66 impl Runnable for VariantB {
67 fn run(&self) {
68 let mut called = self.called.lock().unwrap();
69 *called = true;
70 }
71 }
72
73 #[test]
74 fn custom_derive_test() {
75 let variant_b = VariantB::default();
76 assert!(!variant_b.was_called());
77
78 let ex = TestEnum::B(variant_b);
79 ex.run();
80
81 let variant_b = match ex {
82 TestEnum::A(_) => panic!("this shouldn't be!"),
83 TestEnum::B(b) => b,
84 };
85 assert!(variant_b.was_called());
86 }
87}