You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 lines
1.9 KiB
Rust

/// Implements the `IntoMultitrait` trait on the defined type.
/// ```rust
/// use multi_trait_object::*;
/// struct MyStruct {
/// a: u64,
/// }
///
/// trait MyTrait {}
/// trait MyOtherTrait {}
///
/// impl MyTrait for MyStruct{}
/// impl MyOtherTrait for MyStruct {}
///
/// impl_trait_object!(MyStruct, dyn MyTrait, dyn MyOtherTrait);
/// ```
#[macro_export]
macro_rules! impl_trait_object {
($obj:ty, $($trt:ty),*) => {
impl $crate::IntoMultitrait for $obj {
fn into_multitrait(self) -> $crate::MultitraitObject {
let mut mto = $crate::MultitraitObject::new(self);
$(
mto._register::<$trt>($crate::__fat_pointer!($obj as $trt).vptr);
)*
mto
}
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __fat_pointer {
($v:ty as $t:ty) => {{
let x = ::std::ptr::null::<$v>() as *const $v as *const $t;
#[allow(unused_unsafe)]
unsafe {
std::mem::transmute::<_, $crate::FatPointer>(x)
}
}}
}
/// Registers multiple trait_impl on a multitrait object
/// ```rust
/// use multi_trait_object::*;
/// use std::fmt::{Debug, Display};
///
/// let mto = create_object!(String::new(), dyn Debug, dyn Display);
/// ```
#[macro_export]
macro_rules! create_object {
($v:expr, $($t:ty), +) => {
{
let null_ptr = unsafe {
// SAFETY: We're never accessing the null value
$crate::null_ptr(&$v)
};
let mut mto = $crate::MultitraitObject::new($v);
$(
let vptr = unsafe {
// SAFETY: We're never accessing the null value
let ptr = $crate::null_ptr(&*null_ptr) as *const $t;
std::mem::transmute::<_, $crate::FatPointer>(ptr).vptr
};
mto._register::<$t>(vptr);
)+
mto
}
}
}