is 0.2.0

This crate allows to perform effortless type checks.
Documentation
/// # Examples
///
/// ### Creation of type checking functions
///
/// Syntax:
/// ```rust
/// # use is::is;
/// # struct T; struct E;
/// is! {
///     /// Documentation for function is_t(&value) -> bool
///     /// Checks if value is of type T
///     impl is_t for T;
///
///     // ...
///
///     /// Documentation for function is_e(&value) -> bool
///     /// Checks if value is of type E
///     impl is_e for E; // this ';' is optional
/// }
/// ```
///
/// Simple usage:
/// ```rust
/// # use is::is;
/// // creates function that checks if given value is of type i32
/// is! { impl is_i32 for i32 }
///
/// assert_eq!(is_i32(&42i32), true);
/// assert_eq!(is_i32(&42u32), false);
///
/// // This macro can be used to implement type checking for any type
/// // Generics are implementation defined
/// is! {
///     impl is_vec_u8 for Vec<u8>;
///     impl is_vec_u16 for Vec<u16>;
/// }
///
/// let vecu8: Vec<u8> = vec![42; 3];
/// let vecu16: Vec<u16> = vec![42; 3];
///
/// assert_eq!(is_vec_u8(&vecu8), true);
/// assert_eq!(is_vec_u8(&vecu16), false);
///
/// assert_eq!(is_vec_u16(&vecu16), true);
/// assert_eq!(is_vec_u16(&vecu8), false);
/// ```
#[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! {
            /// This is a doc
            /// of a function
            /// that checks a
            /// type of value
            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);
    }
}