1use std::any::{Any, TypeId};
2
3pub trait Action: 'static {
4 fn id(&self) -> TypeId;
5 fn namespace(&self) -> &'static str;
6 fn name(&self) -> &'static str;
7 fn as_any(&self) -> &dyn Any;
8 fn boxed_clone(&self) -> Box<dyn Action>;
9 fn boxed_clone_as_any(&self) -> Box<dyn Any>;
10}
11
12#[macro_export]
13macro_rules! impl_actions {
14 ($namespace:path, [ $($name:ident),* $(,)? ]) => {
15 $(
16 impl $crate::action::Action for $name {
17 fn id(&self) -> std::any::TypeId {
18 std::any::TypeId::of::<$name>()
19 }
20
21 fn namespace(&self) -> &'static str {
22 stringify!($namespace)
23 }
24
25 fn name(&self) -> &'static str {
26 stringify!($name)
27 }
28
29 fn as_any(&self) -> &dyn std::any::Any {
30 self
31 }
32
33 fn boxed_clone(&self) -> Box<dyn $crate::action::Action> {
34 Box::new(self.clone())
35 }
36
37 fn boxed_clone_as_any(&self) -> Box<dyn std::any::Any> {
38 Box::new(self.clone())
39 }
40 }
41 )*
42 };
43}
44
45#[macro_export]
46macro_rules! actions {
47 ($namespace:path, [ $($name:ident),* $(,)? ]) => {
48
49 $(
50 #[derive(Clone, Debug, Default, PartialEq, Eq)]
51 pub struct $name;
52 )*
53
54 $crate::impl_actions!($namespace, [ $($name),* ]);
55 };
56}