#[macro_export]
macro_rules! is {
($($(#[$docs:meta])* impl $function:ident for $T:ty);+ $(;)*) => {$(
$(#[$docs])*
pub fn $function<V: std::any::Any + ?Sized>(_: &V) -> bool {
std::any::TypeId::of::<$T>() == std::any::TypeId::of::<V>()
}
)*};
}
#[cfg(test)]
mod tests {
#[test]
fn is_with_docs() {
is! {
impl is_u8 for u8;
}
assert_eq!(is_u8(&42u8), true);
assert_eq!(is_u8(&42), false);
}
#[test]
fn is_primitive() {
is! {
impl is_str for str;
impl is_i32 for i32;
}
assert_eq!(is_str("42"), true);
assert_eq!(is_str(&42), false);
assert_eq!(is_i32(&42), true);
assert_eq!(is_i32("42"), false);
}
#[test]
fn is_struct() {
struct A;
struct B;
is! {
impl is_a for A;
impl is_b for B;
}
assert_eq!(is_a(&A{}), true);
assert_eq!(is_a(&B{}), false);
assert_eq!(is_b(&B{}), true);
assert_eq!(is_b(&A{}), false);
}
#[test]
fn is_generic_struct() {
struct A<T> { _a: T }
struct B<T> { _b: T }
is! {
impl is_a for A<i32>;
impl is_b for B<i32>;
}
assert_eq!(is_a(&A{ _a: 42 }), true);
assert_eq!(is_a(&A{ _a: 42.0 }), false);
assert_eq!(is_a(&B{ _b: 42 }), false);
assert_eq!(is_b(&B{ _b: 42 }), true);
assert_eq!(is_b(&B{ _b: 42.0 }), false);
assert_eq!(is_b(&A{ _a: 42 }), false);
}
#[test]
fn is_enum() {
enum E {
A,
B(i32),
C { _a: i32, _b: i32 }
}
is! {
impl is_e for E;
}
assert_eq!(is_e(&E::A), true);
assert_eq!(is_e(&E::B(42)), true);
assert_eq!(is_e(&E::C{ _a: 42, _b: 42 }), true);
assert_eq!(is_e(&42), false);
}
#[test]
fn is_generic_enum() {
enum E<T> {
A,
B(T),
C { _a: T, _b: T }
}
is! {
impl is_e for E<i32>;
}
assert_eq!(is_e(&E::A::<i32>), true);
assert_eq!(is_e(&E::B::<i32>(42)), true);
assert_eq!(is_e(&E::C::<i32>{ _a: 42, _b: 42 }), true);
assert_eq!(is_e(&42), false);
}
}