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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
macro_rules! register_events {
    (
        ($main_event_type_ident: ident, $main_event_ident: ident) {
            $(
                $current_event_type_ident: ident {
                    $current_event_none_ident: ident,
                    $current_event_input_ident: ident,
                    $current_event_output_ident: ident,
                    $current_event_input_output_ident: ident
                }
            ),+
        }
    ) => {
        pub enum $main_event_ident {
            $(
                $current_event_none_ident($current_event_none_ident),
                $current_event_input_ident($current_event_input_ident),
                $current_event_output_ident($current_event_output_ident),
                $current_event_input_output_ident($current_event_input_output_ident)
            ),+
        }

        impl $main_event_ident {
            pub fn new(funcs: Vec<Func>, event_type: $main_event_type_ident, has_input: bool, has_output: bool) -> Result<Self> {
                match event_type {
                    $(
                        $main_event_type_ident::$current_event_type_ident => {
                            let result =
                                if has_input {
                                    if has_output {
                                        let func = try!($current_event_input_output_ident::new(funcs));
                                        $main_event_ident::from(func)
                                    } else {
                                        let func = try!($current_event_input_ident::new(funcs));
                                        $main_event_ident::from(func)
                                    }
                                } else if has_output {
                                    let func = try!($current_event_output_ident::new(funcs));
                                    $main_event_ident::from(func)
                                } else {
                                    let func = try!($current_event_none_ident::new(funcs));
                                    $main_event_ident::from(func)
                                };
                            Ok(result)
                        }
                    ),+
                }
            }

            pub fn enum_to_string(&self) -> &'static str {
                match self {
                    $(
                        &$main_event_ident::$current_event_none_ident(_) => {
                            stringify!($main_event_ident::$current_event_none_ident)
                        },
                        &$main_event_ident::$current_event_input_ident(_) => {
                            stringify!($main_event_ident::$current_event_input_ident)
                        },
                        &$main_event_ident::$current_event_output_ident(_) => {
                            stringify!($main_event_ident::$current_event_output_ident)
                        },
                        &$main_event_ident::$current_event_input_output_ident(_) => {
                            stringify!($main_event_ident::$current_event_input_output_ident)
                        }
                    ),+
                }
            }
        }

        $(
            impl From<$current_event_none_ident> for $main_event_ident {
                fn from(event: $current_event_none_ident) -> $main_event_ident {
                    $main_event_ident::$current_event_none_ident(event)
                }
            }

            impl From<$current_event_input_ident> for $main_event_ident {
                fn from(event: $current_event_input_ident) -> $main_event_ident {
                    $main_event_ident::$current_event_input_ident(event)
                }
            }

            impl From<$current_event_output_ident> for $main_event_ident {
                fn from(event: $current_event_output_ident) -> $main_event_ident {
                    $main_event_ident::$current_event_output_ident(event)
                }
            }

            impl From<$current_event_input_output_ident> for $main_event_ident {
                fn from(event: $current_event_input_output_ident) -> $main_event_ident {
                    $main_event_ident::$current_event_input_output_ident(event)
                }
            }

            impl From<$main_event_ident> for Result<$current_event_none_ident> {
                fn from(event: $main_event_ident) -> Result<$current_event_none_ident> {
                    match event {
                        $main_event_ident::$current_event_none_ident(event) => Ok(event),
                        event => {
                            Err(
                                ErrorKind::EventConversionFailure(
                                    event.enum_to_string().to_string(),
                                    stringify!($main_event_ident::$current_event_none_ident).to_string(),
                                ).into()
                            )
                        },
                    }
                }
            }

            impl From<$main_event_ident> for Result<$current_event_input_ident> {
                fn from(event: $main_event_ident) -> Result<$current_event_input_ident> {
                    match event {
                        $main_event_ident::$current_event_input_ident(event) => Ok(event),
                        event => {
                            Err(
                                ErrorKind::EventConversionFailure(
                                    event.enum_to_string().to_string(),
                                    stringify!($main_event_ident::$current_event_input_ident).to_string(),
                                ).into()
                            )
                        },
                    }
                }
            }

            impl From<$main_event_ident> for Result<$current_event_output_ident> {
                fn from(event: $main_event_ident) -> Result<$current_event_output_ident> {
                    match event {
                        $main_event_ident::$current_event_output_ident(event) => Ok(event),
                        event => {
                            Err(
                                ErrorKind::EventConversionFailure(
                                    event.enum_to_string().to_string(),
                                    stringify!($main_event_ident::$current_event_output_ident).to_string(),
                                ).into()
                            )
                        },
                    }
                }
            }

            impl From<$main_event_ident> for Result<$current_event_input_output_ident> {
                fn from(event: $main_event_ident) -> Result<$current_event_input_output_ident> {
                    match event {
                        $main_event_ident::$current_event_input_output_ident(event) => Ok(event),
                        event => {
                            Err(
                                ErrorKind::EventConversionFailure(
                                    event.enum_to_string().to_string(),
                                    stringify!($main_event_ident::$current_event_input_output_ident).to_string(),
                                ).into()
                            )
                        },
                    }
                }
            }
        )+
    }
}