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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#[doc(hidden)]
#[macro_export]
macro_rules! __msg_send_parse {
    // No arguments
    {
        ($out_macro:path)
        @($error_fn:ident)
        // Intentionally empty
        @()
        @()
        @($selector:ident $(,)?)
        $($macro_args:tt)*
    } => {
        $crate::__msg_send_parse! {
            ($out_macro)
            @($error_fn)
            @($selector)
            @()
            @()
            $($macro_args)*
        }
    };

    // tt-munch remaining `selector: argument` pairs, looking for a pattern
    // that ends with `sel: _`.
    {
        ($out_macro:path)
        @($_error_fn:ident)
        @($($selector_output:tt)*)
        @($($argument_output:tt)*)
        @()
        $($macro_args:tt)*
    } => ({
        $out_macro! {
            $($macro_args)*
            @($($selector_output)*)
            @($($argument_output)*)
        }
    });
    {
        ($out_macro:path)
        @($error_fn:ident)
        @($($selector_output:tt)*)
        @($($argument_output:tt)*)
        @($selector:ident: _ $(,)?)
        @($fn:ident)
        $($macro_args:tt)*
    } => {
        $crate::__msg_send_parse! {
            ($out_macro)
            @($error_fn)
            @($($selector_output)* $selector:)
            // Don't pass an argument
            @($($argument_output)*)
            @()

            // Instead, we change the called function to the error function.
            @($error_fn)
            $($macro_args)*
        }
    };
    {
        ($out_macro:path)
        @($error_fn:ident)
        @($($selector_output:tt)*)
        @($($argument_output:tt)*)
        @($selector:ident : $argument:expr $(, $($rest:tt)*)?)
        $($macro_args:tt)*
    } => {
        $crate::__msg_send_parse! {
            ($out_macro)
            @($error_fn)
            @($($selector_output)* $selector:)
            @($($argument_output)* $argument,)
            @($($($rest)*)?)
            $($macro_args)*
        }
    };

    // Handle calls without comma between `selector: argument` pair.
    // TODO: Deprecate this
    {
        ($out_macro:path)
        @($error_fn:ident)
        // Intentionally empty
        @()
        @()
        @($($selector:ident : $argument:expr)*)
        $($macro_args:tt)*
    } => {
        $crate::__msg_send_parse! {
            ($out_macro)
            @($error_fn)
            @()
            @()
            @($($selector : $argument),*)
            $($macro_args)*
        }
    };
}