multi-any 0.1.1

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

/// Stores fat pointer metadata in a type-erased way.
///
/// Used internally by `MultiAny` to safely downcast to concrete types or trait objects.
///
/// # Fields
/// - `meta_raw`: Raw metadata pointer stored as `usize`.
/// - `data_id`: `TypeId` of the original data type.
/// - `meta_id`: `TypeId` of the metadata type.
///
/// # Safety
/// - `meta_raw` must have been created from a `DynMetadata<T>` or `()`.
/// - `data_id` and `meta_id` must match the data and metadata types exactly.
pub struct Meta {
    pub(crate) meta_raw: usize,
    pub(crate) data_id: TypeId,
    pub(crate) meta_id: TypeId,
}

impl Meta {
    /// Attempts to construct `Meta` for a requested type.
    ///
    /// # Parameters
    /// - `data`: Reference to the concrete data.
    /// - `requested_type_id`: TypeId of the requested type.
    /// - `cast_fn`: Function to cast `&Data` to `&RequestedType`.
    ///
    /// # Returns
    /// - `Some(Meta)` if `requested_type_id` matches `RequestedType`.
    /// - `None` otherwise.
    ///
    /// # Type Parameters
    /// - `Data`: Concrete type stored in the `MultiAny`.
    /// - `RequestedType`: Type to attempt downcasting to.
    pub fn try_from<Data, RequestedType>(
        data: &Data,
        requested_type_id: TypeId,
        cast_fn: fn(&Data) -> &RequestedType,
    ) -> Option<Meta>
    where
        Data: 'static,
        RequestedType: Pointee + ?Sized + 'static,
        RequestedType::Metadata: TypedMetadata,
    {
        if requested_type_id != TypeId::of::<RequestedType>() {
            return None;
        }

        let dyn_trait = cast_fn(data);
        let typed_meta = metadata(dyn_trait);

        RequestedType::Metadata::into_meta::<Data>(typed_meta).into()
    }

    /// Converts this `Meta` into the concrete metadata type for a requested type.
    ///
    /// # Type Parameters
    /// - `Data`: The concrete type stored in the `MultiAny`.
    /// - `RequestedType`: The type whose metadata you want to reconstruct.
    ///
    /// # Returns
    /// The metadata of type `RequestedType::Metadata`.
    pub fn into_metadata<Data, RequestedType>(self) -> RequestedType::Metadata
    where
        Data: 'static,
        RequestedType: Pointee + ?Sized + 'static,
        RequestedType::Metadata: TypedMetadata,
    {
        assert_eq!(self.data_id, TypeId::of::<Data>(), "Wrong Data type");
        RequestedType::Metadata::from_meta(self)
    }
}