Last active
November 16, 2020 10:39
-
-
Save ascjones/e3f82327a4a6653419615c7f7d5b9a53 to your computer and use it in GitHub Desktop.
Revisions
-
ascjones revised this gist
Nov 16, 2020 . 1 changed file with 38 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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>>()) } -
ascjones revised this gist
Nov 11, 2020 . 1 changed file with 123 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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) } -
ascjones created this gist
Nov 11, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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>>()) }