multi-any 0.1.1

`MultiAny` is just like `Any` but can downcast to trait objects.
Documentation
use crate::Meta;
use crate::ptr_metadata::*;
use std::any::TypeId;
use std::mem::transmute;

/// Trait for converting between fat pointer metadata and type-erased `Meta`.
///
/// Implemented for `()` (for concrete types) and `DynMetadata<T>` (for trait objects).
pub trait TypedMetadata {
    /// Converts `Meta` into the corresponding metadata type.
    fn from_meta(meta: Meta) -> Self;

    /// Converts metadata type into a type-erased `Meta`.
    fn into_meta<Data: 'static>(self) -> Meta;
}

impl TypedMetadata for () {
    fn from_meta(meta: Meta) -> Self {
        assert_eq!(meta.meta_id, TypeId::of::<()>(), "Wrong Metadata type");
    }

    fn into_meta<Data: 'static>(self) -> Meta {
        Meta {
            meta_raw: 0,
            data_id: TypeId::of::<Data>(),
            meta_id: TypeId::of::<Self>(),
        }
    }
}

impl<T> TypedMetadata for DynMetadata<T>
where
    T: Pointee<Metadata = Self> + ?Sized + 'static,
{
    fn from_meta(meta: Meta) -> Self {
        assert_eq!(meta.meta_id, TypeId::of::<Self>(), "Wrong Metadata type");

        // SAFETY: We transmute usize to DynMetadata<T>.
        // This is safe because we are sure that usize was acquired by transmuting the exact same type.
        // Note: transmute guarantees that types has the same size.
        let typed_meta: Self = unsafe { transmute(meta.meta_raw) };

        typed_meta
    }

    fn into_meta<Data: 'static>(self) -> Meta {
        // SAFETY: We transmute DynMetadata<T> to usize.
        // This is safe because we will only use the resulting usize to transmute back to the exact same type.
        // Note: transmute guarantees that types has the same size.
        let meta_raw: usize = unsafe { transmute(self) };

        Meta {
            meta_raw,
            data_id: TypeId::of::<Data>(),
            meta_id: TypeId::of::<Self>(),
        }
    }
}