Skip to content

Instantly share code, notes, and snippets.

@ascjones
Last active November 16, 2020 10:39
Show Gist options
  • Save ascjones/e3f82327a4a6653419615c7f7d5b9a53 to your computer and use it in GitHub Desktop.
Save ascjones/e3f82327a4a6653419615c7f7d5b9a53 to your computer and use it in GitHub Desktop.

Revisions

  1. ascjones revised this gist Nov 16, 2020. 1 changed file with 38 additions and 0 deletions.
    38 changes: 38 additions & 0 deletions scale-info-box3.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    use std::any;

    struct Type;

    trait TypeInfo {
    type Type: 'static;
    fn type_info() -> Type;
    }

    impl TypeInfo for u32 {
    type Type = Self;

    fn type_info() -> Type {
    Type
    }
    }

    impl<T> TypeInfo for Box<T>
    where
    T: TypeInfo + 'static
    {
    type Type = T;

    fn type_info() -> Type {
    T::type_info()
    }
    }

    fn type_id<T>() -> any::TypeId
    where
    T: TypeInfo + 'static,
    {
    any::TypeId::of::<T::Type>()
    }

    fn main() {
    println!("{:?} {:?}", type_id::<u32>(), type_id::<Box<u32>>())
    }
  2. ascjones revised this gist Nov 11, 2020. 1 changed file with 123 additions and 0 deletions.
    123 changes: 123 additions & 0 deletions scale-info-box2.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,123 @@
    use std::any;
    use std::marker::PhantomData;

    struct Type;

    trait TypeInfo {
    fn type_info() -> Type;
    }

    impl TypeInfo for u32 {
    fn type_info() -> Type {
    Type
    }
    }

    impl<T> TypeInfo for Box<T>
    where
    T: TypeInfo + 'static
    {
    fn type_info() -> Type {
    T::type_info()
    }
    }

    impl<T: ?Sized> scale::WrapperTypeEncode for Box<T> {}

    struct MetaType {
    type_id: any::TypeId,
    fn_type_info: fn() -> Type
    }

    mod scale {
    use std::ops::Deref;
    pub trait WrapperTypeEncode: Deref {}
    }

    impl MetaType {
    pub fn new<T>() -> Self
    where
    T: TypeInfo + ?Sized + 'static,
    {
    Self {
    fn_type_info: <T as TypeInfo>::type_info,
    type_id: any::TypeId::of::<T>(),
    }
    }

    pub fn new_deref<T, U>() -> Self
    where
    T: scale::WrapperTypeEncode<Target = U>,
    U: TypeInfo + ?Sized + 'static,
    {
    Self {
    fn_type_info: <U as TypeInfo>::type_info,
    type_id: any::TypeId::of::<U>(),
    }
    }
    }

    ///
    struct TypeInfoTag<T>(PhantomData<T>);

    trait TypeInfoKind {
    type Type: TypeInfo + 'static;

    #[inline]
    fn kind(&self) -> TypeInfoTag<Self::Type> {
    TypeInfoTag(PhantomData)
    }
    }

    impl<T: TypeInfo + 'static> TypeInfoTag<T> {
    #[inline]
    fn new(self) -> MetaType {
    MetaType::new::<T>()
    }
    }

    // Requires one extra autoref to call! Lower priority than WrapperTypeKind.
    impl<T: TypeInfo + 'static> TypeInfoKind for &PhantomData<T> {
    type Type = T;
    }

    ///
    struct WrapperTypeTag<T>(PhantomData<T>);

    trait WrapperTypeKind {
    type Type: scale::WrapperTypeEncode<Target = Self::Target>;
    type Target: TypeInfo + 'static;

    #[inline]
    fn kind(&self) -> WrapperTypeTag<Self::Type> {
    WrapperTypeTag(PhantomData)
    }
    }

    // Does not require any autoref if called as (&error).anyhow_kind().
    impl<T: scale::WrapperTypeEncode<Target = U>, U: TypeInfo + 'static> WrapperTypeKind for PhantomData<T> {
    type Type = T;
    type Target = U;
    }

    impl<T: scale::WrapperTypeEncode<Target = U>, U: TypeInfo + 'static> WrapperTypeTag<T> {
    #[inline]
    fn new(self) -> MetaType {
    MetaType::new_deref::<T, U>()
    }
    }

    macro_rules! meta_type {
    ($meta_type:ty) => ({
    #[allow(unused_imports)]
    use $crate::{TypeInfoKind, WrapperTypeKind};
    let meta_type = PhantomData::<$meta_type>;
    (&meta_type).kind().new()
    });
    }

    fn main() {
    let ty = meta_type!(u32);
    let ty2 = meta_type!(Box<u32>);
    println!("{:?} {:?}", ty.type_id, ty2.type_id)
    }
  3. ascjones created this gist Nov 11, 2020.
    44 changes: 44 additions & 0 deletions scale-info-box1.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,44 @@
    use std::any;

    struct Type;

    trait TypeInfo {
    fn type_info() -> Type;

    fn wrapped_type_id() -> Option<any::TypeId> {
    None
    }
    }

    impl TypeInfo for u32 {
    fn type_info() -> Type {
    Type
    }
    }

    impl<T> TypeInfo for Box<T>
    where
    T: TypeInfo + 'static
    {
    fn type_info() -> Type {
    T::type_info()
    }

    fn wrapped_type_id() -> Option<any::TypeId> {
    Some(any::TypeId::of::<T>())
    }
    }

    fn type_id<T>() -> any::TypeId
    where
    T: TypeInfo + 'static,
    {
    match T::wrapped_type_id() {
    None => any::TypeId::of::<T>(),
    Some(id) => id,
    }
    }

    fn main() {
    println!("{:?} {:?}", type_id::<u32>(), type_id::<Box<u32>>())
    }