1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use std::any::{Any, TypeId};

/// Condition type between two values.
///
/// ```rust
///   assert_eq!(types::ty_cond(&0, &1), true); // true
///   assert_ne!(types::ty_cond(&0, &String::default()), true); // true
/// ```
pub fn ty_cond<T: ?Sized + Any, R: ?Sized + Any>(_s: &T, _r: &R) -> bool {
    TypeId::of::<T>() == TypeId::of::<R>()
}

macro_rules! impl_tys {
    (
        $(($type: ty, $func: ident),)*
    ) => {
        /// Type condition Sets
        ///
        /// Note: prefer to use `ty_cond`, not this.
        pub trait Conds {
            $(fn $func(self) -> bool;)*
        }

        impl<T: Sized + Any> Conds for T {
            $(
                fn $func(self) -> bool {
                    TypeId::of::<$type>() == TypeId::of::<Self>()
                }
            )*
        }
    };
}

impl_tys! (
    // primitive
    (i8, is_i8),
    (i16, is_i16),
    (i32, is_i32),
    (i64, is_i64),
    (i128, is_i128),

    (u8, is_u8),
    (u16, is_u16),
    (u32, is_u32),
    (u64, is_u64),
    (u128, is_u128),

    (f32, is_f32),
    (f64, is_f64),

    (isize, is_isize),
    (usize, is_usize),
    
    (bool, is_bool),
    (char, is_char),
    (&'static str, is_str),

    // alloc
    (String, is_string),
);