frc42_dispatch/
match_method.rs

1#[macro_export]
2macro_rules! match_method {
3    ($method:expr, {$($body:tt)*}) => {
4        match_method!{@match $method, {}, $($body)*}
5    };
6    (@match $method:expr, {$($body:tt)*}, $(,)*) => {
7        match $method {
8            $($body)*
9        }
10    };
11    // matches block with comma
12    (@match $method:expr, {$($body:tt)*}, $p:literal => $e:expr, $($tail:tt)*) => {
13        match_method! {
14            @match
15            $method,
16            {
17                $($body)*
18                $crate::method_hash!($p) => $e,
19            },
20            $($tail)*
21        }
22    };
23    // matches block without comma
24    (@match $method:expr, {$($body:tt)*}, $p:literal => $e:block $($tail:tt)*) => {
25        match_method! {
26            @match
27            $method,
28            {
29                $($body)*
30                $crate::method_hash!($p) => $e,
31            },
32            $($tail)*
33        }
34    };
35    // matches _ with a trailing comma
36    (@match $method:expr, {$($body:tt)*}, _ => $e:expr, $($tail:tt)*) => {
37        match_method! {
38            @match
39            $method,
40            {
41                $($body)*
42                _ => $e,
43            },
44            $($tail)*
45        }
46    };
47    // matches _ without a trailing comma (common if it's the last item)
48    (@match $method:expr, {$($body:tt)*}, _ => $e:expr) => {
49        match_method! {
50            @match
51            $method,
52            {
53                $($body)*
54                _ => $e,
55            },
56        }
57    };
58}
59
60#[cfg(test)]
61mod tests {
62    #[test]
63    fn handle_constructor() {
64        let method_num = 1u64; // constructor should always hash to 1
65        let ret = match_method!(method_num, {
66            "Constructor" => Some(1),
67            _ => None,
68        });
69
70        assert_eq!(ret, Some(1));
71    }
72
73    #[test]
74    fn handle_unknown_method() {
75        let method_num = 12345u64; // not a method we know about
76        let ret = match_method!(method_num, {
77            "Constructor" => Some(1),
78            _ => None,
79        });
80
81        assert_eq!(ret, None);
82    }
83
84    #[test]
85    fn handle_user_method() {
86        let method_num = crate::method_hash!("TokensReceived");
87        let ret = match_method!(method_num, {
88            "Constructor" => Some(1),
89            "TokensReceived" => Some(2),
90            _ => None,
91        });
92
93        assert_eq!(ret, Some(2));
94    }
95
96    #[test]
97    fn handle_optional_commas() {
98        let method_num = crate::method_hash!("TokensReceived");
99        let ret = match_method!(method_num, {
100            "Constructor" => Some(1),
101            "TokensReceived" => {
102                Some(2)
103            }
104            _ => {
105                None
106            }
107        });
108
109        assert_eq!(ret, Some(2));
110    }
111}