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
//! Macros used across the ibc-rs crates.

/// Downcast an enum variant that contains a single value into its inner value.
///
/// ## Note
/// Only works for enums whose variants only hold a single value.
///
/// ## Example
///
/// ```rust
/// use ibc_primitives::downcast;
///
/// enum Foo {
///     Bar(u32),
///     Baz(bool),
/// }
///
/// let bar = Foo::Bar(42);
/// let baz = Foo::Baz(true);
///
/// if let Some(value) = downcast!(bar => Foo::Bar) {
///     println!("value is a u32: {}", value);
/// }
///
/// if let Some(value) = downcast!(baz => Foo::Baz) {
///     println!("value is a bool: {}", value);
/// }
///
/// if let Some((a, b)) = downcast!(bar => Foo::Bar, baz => Foo::Baz) {
///     println!("a is a u32: {}", a);
///     println!("b is a bool: {}", b);
/// }
/// ```
#[macro_export]
macro_rules! downcast {
    ( $e1:expr => $p1:path, $( $e:expr => $p:path ),+ $(,)? ) => {
        downcast!($e1 => $p1).zip(downcast!($($e => $p),+))
    };

    ($e:expr => $p:path) => {
        match $e {
            $p(e) => Some(e),
            #[allow(unreachable_patterns)]
            _ => None,
        }
    };

    () => {
        None
    }
}