Last active
November 16, 2020 10:39
-
-
Save ascjones/e3f82327a4a6653419615c7f7d5b9a53 to your computer and use it in GitHub Desktop.
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 characters
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>>()) | |
} |
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 characters
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) | |
} |
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 characters
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>>()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment