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}