/// Asserts that actual variant is the same as the expected variant, regardless of the value of their fields.
/// The enum is required to implement the Debug trait.
///
/// # Usage
/// ```
/// # #[derive(Debug)]
/// # enum TestEnum { A }
/// # #[macro_use] extern crate assertx;
/// # fn main() {
/// #   let actual = TestEnum::A;
/// #   let expected = TestEnum::A;
///     assert_same_variant!(actual, expected);
/// # }
/// ```
///
/// # Examples
///
/// Will succeed, both variants are the same
/// ```
/// # #[derive(Debug)]
/// # enum TestEnum { A }
/// # #[macro_use] extern crate assertx;
/// # fn main() {
///     assert_same_variant!(TestEnum::A, TestEnum::A)
/// # }
/// ```
///
/// Will succeed, both variants are the same even if the fields aren't.
/// ```
/// # #[derive(Debug)]
/// # enum TestEnum { A(u8) }
/// # #[macro_use] extern crate assertx;
/// # fn main() {
///     assert_same_variant!(TestEnum::A(2), TestEnum::A(6))
/// # }
/// ```
///
/// Will fail, actual variant differs from the expectation
/// ```should_panic
/// # #[derive(Debug)]
/// # enum TestEnum { A, B }
/// # #[macro_use] extern crate assertx;
/// # fn main() {
///     assert_same_variant!(TestEnum::B, TestEnum::A)
/// # }
/// ```
#[macro_export]
macro_rules! assert_same_variant {
    ($left:expr, $right:expr) => {{
        if std::mem::discriminant(&$left) != std::mem::discriminant(&$right) {
            panic!(
                "assertion failed: `(left == right)`\n\t\tleft: `{:?}`\n\t\tright: `{:?}`",
                &$left, &$right
            )
        }
    }};
}

#[cfg(test)]
mod tests {
    #[derive(Debug)]
    enum TestEnum {
        A { val: u8 },
        B(u32),
    }

    #[test]
    #[should_panic(
        expected = "assertion failed: `(left == right)`\n\t\tleft: `A { val: 4 }`\n\t\tright: `B(8)`"
    )]
    fn should_panic_if_not_same_variant() {
        assert_same_variant!(TestEnum::A { val: 4 }, TestEnum::B(8))
    }

    #[test]
    fn should_not_panic_if_same_variant() {
        assert_same_variant!(TestEnum::B(8), TestEnum::B(4))
    }
}
