Skip to main content

rdif_base/
_macros.rs

1/// Defines a driver type that wraps a boxed trait object.
2///
3/// $name: driver name
4///
5/// $tr: driver trait path
6#[macro_export]
7macro_rules! def_driver {
8    ($name:ident, $tr:path) => {
9        $crate::paste! {
10            pub mod [<$name:lower>]{
11                use super::*;
12                pub struct $name(alloc::boxed::Box<dyn $tr>);
13
14                impl $name {
15                    pub fn new<T: $tr>(driver: T) -> Self {
16                        Self(alloc::boxed::Box::new(driver))
17                    }
18
19                    pub fn typed_ref<T: $tr>(&self) -> Option<&T> {
20                        self.raw_any()?.downcast_ref()
21                    }
22
23                    pub fn typed_mut<T: $tr>(&mut self) -> Option<&mut T> {
24                        self.raw_any_mut()?.downcast_mut()
25                    }
26                }
27
28                impl $crate::DriverGeneric for $name {
29                    fn name(&self) -> &str {
30                        self.0.name()
31                    }
32
33                    fn raw_any(&self) -> Option<&dyn core::any::Any> {
34                        Some( self.0.as_ref() as &dyn core::any::Any )
35                    }
36
37                    fn raw_any_mut(&mut self) -> Option<&mut dyn core::any::Any> {
38                        Some( self.0.as_mut() as &mut dyn core::any::Any )
39                    }
40                }
41
42                impl core::ops::Deref for $name {
43                    type Target = dyn $tr;
44
45                    fn deref(&self) -> &Self::Target {
46                        self.0.as_ref()
47                    }
48                }
49
50                impl core::ops::DerefMut for $name {
51                    fn deref_mut(&mut self) -> &mut Self::Target {
52                        self.0.as_mut()
53                    }
54                }
55            }
56            pub use [<$name:lower>]::$name;
57        }
58    };
59}