multi-trait-object 0.2.0

A type to store an object with all associated traits
Documentation
use std::fmt::Debug;
use crate::{__fat_pointer, impl_trait_object, IntoMultitrait, TryClone, TryPartialEq, RawClone, PartialEqAny, create_object};

#[derive(Clone, Debug, Eq, PartialEq)]
struct TestStruct {
    a: u32,
    test: String,
}

impl Default for TestStruct {
    fn default() -> Self {
        Self {
            a: 5,
            test: String::from("Hello World"),
        }
    }
}

trait ChangeStruct {
    fn update(&mut self);
}

impl ChangeStruct for TestStruct {
    fn update(&mut self) {
        self.a = 6;
    }
}

impl_trait_object!(TestStruct, dyn RawClone, dyn PartialEqAny, dyn ChangeStruct, dyn Debug);

#[test]
fn it_creates_fat_pointers() {
    let debug_vtable1 = __fat_pointer!(TestStruct as dyn Debug).vptr;
    let dclone_vtable1 = __fat_pointer!(TestStruct as dyn RawClone).vptr;
    let debug_vtable2 = __fat_pointer!(TestStruct as dyn Debug).vptr;
    assert_eq!(debug_vtable1, debug_vtable2);
    let dclone_vtable2 = __fat_pointer!(TestStruct as dyn RawClone).vptr;
    assert_eq!(dclone_vtable1, dclone_vtable2);
}

#[test]
fn it_constructs() {
    TestStruct::default().into_multitrait();
    String::from("test").into_multitrait();
    let mto = create_object!(String::from("test"), dyn Debug);
    assert!(mto.is::<String>())
}

#[test]
fn it_downcasts_traits() {
    let mto = TestStruct::default().into_multitrait();
    let debug = mto.downcast_trait::<dyn Debug>().unwrap();
    let _ = format!("{:?}", debug);
}

#[test]
fn it_downcasts_trait_mutable() {
    let mut mto = TestStruct::default().into_multitrait();
    let change_struct = mto.downcast_trait_mut::<dyn ChangeStruct>().unwrap();
    change_struct.update();
}

#[test]
fn it_downcasts_boxed_traits() {
    let mto = TestStruct::default().into_multitrait();
    let boxed = mto.downcast_trait_boxed::<dyn Debug>().unwrap();
    let _ = format!("{:?}", boxed);
}

#[test]
fn it_downcasts_to_original() {
    let mut mto = TestStruct::default().into_multitrait();
    {
        mto.downcast_ref::<TestStruct>().unwrap();
    }
    {
        mto.downcast_mut::<TestStruct>().unwrap();
    }
    let result = mto.downcast::<TestStruct>().unwrap();
    assert_eq!(result.a, 5);
    assert_eq!(result.test, String::from("Hello World"));
}

#[test]
fn it_tries_cloning() {
    let mto = TestStruct::default().into_multitrait();
    let mto2 = mto.try_clone().unwrap();
    let obj1 = mto.downcast::<TestStruct>();
    let obj2 = mto2.downcast::<TestStruct>();
    assert_eq!(obj1, obj2);
}

#[test]
fn it_returns_type_information() {
    let mto = TestStruct::default().into_multitrait();
    assert!(mto.is::<TestStruct>());
    assert!(mto.implements::<dyn Debug>());
    assert!(mto.implements::<dyn ChangeStruct>());
}

#[test]
fn it_tries_partial_eq() {
    let mto = TestStruct::default().into_multitrait();
    let mto_eq = TestStruct::default().into_multitrait();
    let mto_neq = TestStruct {test: String::from("no"), a: 6}.into_multitrait();
    assert!(mto.try_eq(&mto_eq).unwrap());
    assert_eq!(mto.try_eq(&mto_neq).unwrap(), false);
}