action.rs

 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}