callable 0.5.0

callable closures implementing PartialEq and argument operations
Documentation
use crate::{Callable, IsCallable};

#[derive(Clone, Copy)]
pub enum NeverCalled {}

impl IsCallable for NeverCalled {}
impl<Args: super::Tuple> Callable<Args> for NeverCalled {
    type Output = ();

    fn call_fn(&self, _: Args) -> Self::Output {
        match *self {}
    }
}

pub trait StatedEvent {
    type State;
}

pub trait MaybeHandleEvent<E: ?Sized + StatedEvent> {
    type State;
    type Callable: for<'e> Callable<(&'e E,)>;

    fn initialize_handle_event_state(
        this: Self,
        new_event_state: impl FnOnce(&Self::Callable) -> E::State,
    ) -> Self::State;

    fn update_handle_event_state(
        this: Self,
        state: &mut Self::State,
        new_event_state: impl FnOnce(&Self::Callable) -> E::State,
    );
}

impl<E: ?Sized + StatedEvent> MaybeHandleEvent<E> for () {
    type State = ();
    type Callable = NeverCalled;

    fn initialize_handle_event_state(
        _: Self,
        _: impl FnOnce(&Self::Callable) -> <E as StatedEvent>::State,
    ) -> Self::State {
    }

    fn update_handle_event_state(
        _: Self,
        _: &mut Self::State,
        _: impl FnOnce(&Self::Callable) -> <E as StatedEvent>::State,
    ) {
    }
}

impl<E: ?Sized + StatedEvent, C: PartialEq + for<'e> Callable<(&'e E,)>> MaybeHandleEvent<E> for C {
    type State = (E::State, C);
    type Callable = C;

    fn initialize_handle_event_state(
        this: Self,
        new_event_state: impl FnOnce(&Self::Callable) -> <E as StatedEvent>::State,
    ) -> Self::State {
        (new_event_state(&this), this)
    }

    fn update_handle_event_state(
        this: Self,
        state: &mut Self::State,
        new_event_state: impl FnOnce(&Self::Callable) -> <E as StatedEvent>::State,
    ) {
        if this != state.1 {
            *state = Self::initialize_handle_event_state(this, new_event_state)
        }
    }
}

impl<E: ?Sized + StatedEvent, M: MaybeHandleEvent<E>> MaybeHandleEvent<E> for Option<M> {
    type State = Option<M::State>;
    type Callable = M::Callable;

    fn initialize_handle_event_state(
        this: Self,
        new_event_state: impl FnOnce(&Self::Callable) -> <E as StatedEvent>::State,
    ) -> Self::State {
        this.map(|this| M::initialize_handle_event_state(this, new_event_state))
    }

    fn update_handle_event_state(
        this: Self,
        state: &mut Self::State,
        new_event_state: impl FnOnce(&Self::Callable) -> <E as StatedEvent>::State,
    ) {
        match (this, state) {
            (None, None) => {}
            (None, state @ Some(_)) => *state = None,
            (Some(this), Some(state)) => M::update_handle_event_state(this, state, new_event_state),
            (Some(this), state @ None) => {
                *state = Some(M::initialize_handle_event_state(this, new_event_state))
            }
        }
    }
}