multi_trait_object/
macros.rs

1/// Implements the `IntoMultitrait` trait on the defined type.
2/// ```rust
3/// use multi_trait_object::*;
4/// struct MyStruct {
5///     a: u64,
6/// }
7///
8/// trait MyTrait {}
9/// trait MyOtherTrait {}
10///
11/// impl MyTrait for MyStruct{}
12/// impl MyOtherTrait for MyStruct {}
13///
14/// impl_trait_object!(MyStruct, dyn MyTrait, dyn MyOtherTrait);
15/// ```
16#[macro_export]
17macro_rules! impl_trait_object {
18    ($obj:ty, $($trt:ty),*) => {
19        impl $crate::IntoMultitrait for $obj {
20            fn into_multitrait(self) -> $crate::MultitraitObject {
21                let mut mto = $crate::MultitraitObject::new(self);
22                $(
23                    mto._register::<$trt>($crate::__fat_pointer!($obj as $trt).vptr);
24                )*
25
26                mto
27            }
28        }
29    }
30}
31
32#[doc(hidden)]
33#[macro_export]
34macro_rules! __fat_pointer {
35    ($v:ty as $t:ty) => {{
36        let x = ::std::ptr::null::<$v>() as *const $v as *const $t;
37        #[allow(unused_unsafe)]
38        unsafe {
39            std::mem::transmute::<_, $crate::FatPointer>(x)
40        }
41    }}
42}
43
44/// Registers multiple trait_impl on a multitrait object
45/// ```rust
46/// use multi_trait_object::*;
47/// use std::fmt::{Debug, Display};
48///
49/// let mto = create_object!(String::new(), dyn Debug, dyn Display);
50/// ```
51#[macro_export]
52macro_rules! create_object {
53    ($v:expr, $($t:ty), +) => {
54        {
55            let null_ptr = unsafe {
56                // SAFETY: We're never accessing the null value
57                $crate::null_ptr(&$v)
58            };
59            let mut mto = $crate::MultitraitObject::new($v);
60            $(
61                let vptr = unsafe {
62                    // SAFETY: We're never accessing the null value
63                    let ptr = $crate::null_ptr(&*null_ptr) as *const $t;
64                    std::mem::transmute::<_, $crate::FatPointer>(ptr).vptr
65                };
66                mto._register::<$t>(vptr);
67            )+
68            mto
69        }
70    }
71}