#![no_std]
#![feature(specialization, macro_vis_matcher, macro_at_most_once_rep, allow_internal_unstable,
use_extern_macros)]
#[allow(unused_imports)] extern crate unhygienic;
#[doc(hidden)] pub use unhygienic::unhygienic_item;
#[doc(hidden)] pub use unhygienic::unhygienic_item_impl;
#[allow(unused_imports)] use core::fmt::Debug;
pub trait Event {
type State;
type StateArg;
type MethodRetVal;
type RetVal;
fn starting_state(&self, _: &impl EventDispatch) -> Self::State;
fn borrow_state<'a>(&self, _: &'a mut Self::State) -> &'a mut Self::StateArg;
fn default_return(&self) -> Self::MethodRetVal;
fn to_event_result(&self, _: &mut Self::State, _: Self::MethodRetVal) -> EventResult;
fn to_return_value(&self, _: &impl EventDispatch, _: Self::State) -> Self::RetVal;
}
#[macro_export]
#[allow_internal_unstable]
macro_rules! simple_event {
($ev:ty $(,)?) => {
simple_event!($ev, (), ());
};
($ev:ty, $state:ty $(,)?) => {
simple_event!($ev, $state, Default::default());
};
($ev:ty, $state:ty, $starting_val:expr $(,)?) => {
impl $crate::Event for $ev {
type State = $state;
type StateArg = $state;
type MethodRetVal = EventResult;
type RetVal = $state;
fn starting_state(&self, _: &impl $crate::EventDispatch) -> $state {
$starting_val
}
fn borrow_state<'a>(&self, state: &'a mut $state) -> &'a mut $state {
state
}
fn default_return(&self) -> EventResult {
Default::default()
}
fn to_event_result(&self, _: &mut $state, result: EventResult) -> EventResult {
result
}
fn to_return_value(
&self, _: &impl $crate::EventDispatch, state: $state,
) -> $state {
state
}
}
};
}
#[macro_export]
#[allow_internal_unstable]
macro_rules! failable_event {
($ev:ty, $state:ty, $error:ty $(,)?) => {
failable_event!($ev, $state, $error, Default::default());
};
($ev:ty, $state:ty, $error:ty, $starting_val:expr $(,)?) => {
impl $crate::Event for $ev {
type State = Result<$state, $error>;
type StateArg = $state;
type MethodRetVal = Result<EventResult, $error>;
type RetVal = Result<$state, $error>;
fn starting_state(&self, _: &impl $crate::EventDispatch) -> Result<$state, $error> {
Ok($starting_val)
}
fn borrow_state<'a>(&self, state: &'a mut Result<$state, $error>) -> &'a mut $state {
state.as_mut().expect("Continuing already failed event?")
}
fn default_return(&self) -> Result<EventResult, $error> {
Ok(Default::default())
}
fn to_event_result(
&self, state: &mut Result<$state, $error>, result: Result<EventResult, $error>,
) -> EventResult {
match result {
Ok(result) => result,
Err(err) => {
*state = Err(err);
EvCancel
}
}
}
fn to_return_value(
&self, _: &impl $crate::EventDispatch, state: Result<$state, $error>,
) -> Result<$state, $error> {
state
}
}
};
}
#[macro_export]
#[allow_internal_unstable]
macro_rules! ipc_event {
($ev:ty $(,)?) => {
ipc_event!($ev, ());
};
($ev:ty, $state:ty $(,)?) => {
impl $crate::Event for $ev {
type State = Option<$state>;
type StateArg = Option<$state>;
type MethodRetVal = EventResult;
type RetVal = $state;
fn starting_state(&self, _: &impl $crate::EventDispatch) -> Option<$state> {
None
}
fn borrow_state<'a>(&self, state: &'a mut Option<$state>) -> &'a mut Option<$state> {
state
}
fn default_return(&self) -> EventResult {
Default::default()
}
fn to_event_result(&self, _: &mut Option<$state>, result: EventResult) -> EventResult {
result
}
fn to_return_value(
&self, _: &impl $crate::EventDispatch, state: Option<$state>,
) -> $state {
state.expect(concat!("No listeners responded to ", stringify!($ev), "!"))
}
}
};
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum EventResult {
EvOk,
EvCancelStage,
EvCancel,
}
pub use self::EventResult::{EvOk, EvCancelStage, EvCancel};
impl Default for EventResult {
fn default() -> Self {
EvOk
}
}
impl From<()> for EventResult {
fn from(_: ()) -> Self {
EvOk
}
}
macro_rules! handlers {
($($ev:ident)*) => {
pub trait EventHandler<E: Event> : EventRoot {
$(
fn $ev(
&self, _: &impl EventDispatch, event: &mut E, _: &mut E::StateArg,
) -> E::MethodRetVal {
event.default_return()
}
)*
}
impl <E: Event, T: EventRoot> EventHandler<E> for T {
$(
default fn $ev(
&self, _: &impl EventDispatch, event: &mut E, _: &mut E::StateArg,
) -> E::MethodRetVal {
event.default_return()
}
)*
}
pub trait EventRoot: Sized { }
pub trait EventSet: Sized {
$(
fn $ev<E: Event>(
&self, target: &impl EventDispatch, ev: &mut E, state: &mut E::State,
) -> EventResult;
)*
}
impl <T: EventRoot> EventSet for T {
$(
fn $ev<E: Event>(
&self, target: &impl EventDispatch, ev: &mut E, state: &mut E::State,
) -> EventResult {
let result = {
let state_arg = ev.borrow_state(state);
EventHandler::$ev(self, target, ev, state_arg)
};
ev.to_event_result(state, result)
}
)*
}
};
}
handlers!(init check before_event on_event after_event);
#[macro_export]
#[doc(hidden)]
macro_rules! event_handler_internal {
(@verify_name init $($rest:tt)*) => { $($rest)* };
(@verify_name check $($rest:tt)*) => { $($rest)* };
(@verify_name before_event $($rest:tt)*) => { $($rest)* };
(@verify_name on_event $($rest:tt)*) => { $($rest)* };
(@verify_name after_event $($rest:tt)*) => { $($rest)* };
(@verify_name $unknown:ident $($rest:tt)*) => {
compile_error!(concat!("Unknown event handler stage '", stringify!($unknown), "'."))
};
($ty:ty, $event:ty, on_call: |$target:pat, $ev:pat,| $ev_func:expr) => {
fn on_event(
&self, target: &impl $crate::EventDispatch,
ev: &mut $event,
state: &mut Option<<$event as $crate::Event>::RetVal>,
) -> <$event as $crate::Event>::MethodRetVal {
use $crate::{Event as __static_events__generated_Event,
EventDispatch as __static_events__generated_EventDispatch};
trait SelfHack {
fn callback(
&self, _: &impl $crate::EventDispatch,
_: &mut $event,
) -> <$event as $crate::Event>::RetVal;
}
unhygienic_item! {
impl SelfHack for $ty {
fn callback(
&self, $target: &impl __static_events__generated_EventDispatch,
$ev: &mut $event,
) -> <$event as __static_events__generated_Event>::RetVal {
$ev_func
}
}
}
if state.is_some() {
panic!(concat!("Duplicate listeners responding to '", stringify!($event), "'."));
}
let call_result = <Self as SelfHack>::callback(self, target, ev);
*state = Some(call_result);
Default::default()
}
};
($ty:ty, $event:ty, $call_name:ident: |$target:pat, $ev:pat, $state:pat,| $ev_func:expr) => {
event_handler_internal!(@verify_name $call_name);
fn $call_name(
&self, target: &impl $crate::EventDispatch,
ev: &mut $event,
state: &mut <$event as $crate::Event>::StateArg,
) -> <$event as $crate::Event>::MethodRetVal {
use $crate::{Event as __static_events__generated_Event,
EventDispatch as __static_events__generated_EventDispatch};
trait SelfHack {
fn callback(
&self, _: &impl $crate::EventDispatch,
_: &mut $event,
_: &mut <$event as $crate::Event>::StateArg,
) -> <$event as $crate::Event>::MethodRetVal;
}
unhygienic_item! {
impl SelfHack for $ty {
fn callback(
&self, $target: &impl __static_events__generated_EventDispatch,
$ev: &mut $event,
$state: &mut <$event as __static_events__generated_Event>::StateArg,
) -> <$event as __static_events__generated_Event>::MethodRetVal {
$ev_func.into()
}
}
}
<Self as SelfHack>::callback(self, target, ev, state)
}
};
($ty:ty, $event:ty, $call_name:ident: |$($bind:pat,)*| $ev_func:expr) => {
event_handler_internal!(@verify_name $call_name
compile_error!(concat!("Wrong number of parameters for event handler stage '",
stringify!($call_name), "'."))
);
};
}
#[macro_export]
#[allow_internal_unstable]
macro_rules! event_handler {
(
$name:ty, $(
$event:ty: {
$($call_name:ident: |$($bind:pat),* $(,)?| $ev_func:expr),*
$(,)?
}
),*
$(,)?
) => {$(
impl $crate::EventHandler<$event> for $name {
$( event_handler_internal!($name, $event, $call_name: |$($bind,)*| $ev_func); )*
}
)*};
}
#[macro_export]
#[allow_internal_unstable]
macro_rules! simple_event_handler {
(
$(#[$meta:meta])* $vis:vis $name:ident, $(
$event:ty: {
$($call_name:ident: |$($bind:pat),* $(,)?| $ev_func:expr),*
$(,)?
}
),*
$(,)?
) => {
#[derive(Copy, Clone, Debug, Default)]
$(#[$meta])*
$vis struct $name;
impl $crate::EventRoot for $name { }
event_handler!($name, $(
$event: {$($call_name: |$($bind,)*| $ev_func,)*},
)*);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! merged_eventset_handler {
($ev:ident, $($field_name:ident)*) => {
fn $ev<E: $crate::Event>(
&self, target: &impl $crate::EventDispatch, ev: &mut E, state: &mut E::State,
) -> $crate::EventResult {
$(
match $crate::EventSet::$ev(&self.$field_name, target, ev, state) {
$crate::EvOk => { }
e => return e,
}
)*
$crate::EvOk
}
}
}
#[macro_export]
#[allow_internal_unstable]
macro_rules! merged_eventset {
($(
$(#[$meta:meta])*
$vis:vis struct $name:ident $(<$($ty_param:ident $(: $ty_bound:path)?),* $(,)?>)? {
$(
$(#[$field_meta:meta])* $field_vis:vis $field_name:ident: $field_type:ty
),* $(,)?
}
)*) => {$(
$(#[$meta])*
$vis struct $name $(<$($ty_param $(: $ty_bound)?,)*>)? {
$($(#[$field_meta])* $field_vis $field_name: $field_type,)*
}
impl $(<$($ty_param $(: $ty_bound)?,)*>)? $crate::EventSet for $name $(<$($ty_param)*>)? {
merged_eventset_handler!(init , $($field_name)*);
merged_eventset_handler!(check , $($field_name)*);
merged_eventset_handler!(before_event, $($field_name)*);
merged_eventset_handler!(on_event , $($field_name)*);
merged_eventset_handler!(after_event , $($field_name)*);
}
)*}
}
pub trait EventDispatch {
fn dispatch<E: Event>(&self, _: E) -> E::RetVal;
}
impl <T: EventSet> EventDispatch for T {
fn dispatch<E: Event>(&self, mut ev: E) -> E::RetVal {
let mut state = ev.starting_state(self);
macro_rules! do_phase {
($ev:ident) => { match self.$ev(self, &mut ev, &mut state) {
EvOk | EvCancelStage => { }
EvCancel => return ev.to_return_value(self, state),
} }
}
do_phase!(init);
do_phase!(check);
do_phase!(before_event);
do_phase!(on_event);
do_phase!(after_event);
ev.to_return_value(self, state)
}
}