matchmaker/render/
dynamic.rs

1use std::fmt;
2
3use super::EphemeralState;
4use crate::{
5    PickerItem, Selection,
6    message::{Interrupt, Event},
7};
8
9// note: beware that same handler could be called multiple times for the same event in one iteration
10// We choose not to return a Option<Result<S, E>> to simplify defining handlers, but will rather expose some mechanisms on state later on if a use case arises
11pub type DynamicMethod<T, S, C, E> = Box<dyn Fn(EphemeralState<'_, T, S, C>, &E) + Send + Sync>;
12pub type DynamicHandlers<T, S, C> = (EventHandlers<T, S, C>, InterruptHandlers<T, S, C>);
13pub struct EventHandlers<T: PickerItem, S: Selection, C> {
14    handlers: Vec<(Vec<Event>, DynamicMethod<T, S, C, Event>)>,
15}
16
17pub struct InterruptHandlers<T: PickerItem, S: Selection, C> {
18    handlers: Vec<(Interrupt, Vec<DynamicMethod<T, S, C, Interrupt>>)>,
19}
20
21impl<T: PickerItem, S: Selection, C> EventHandlers<T, S, C> {
22    pub fn new() -> Self {
23        Self { handlers: vec![] }
24    }
25
26    pub fn set(&mut self, events: Vec<Event>, handler: DynamicMethod<T, S, C, Event>) {
27        self.handlers.push((events, handler));
28    }
29
30    pub fn get(
31        &self,
32        event: &Event,
33    ) -> impl Iterator<Item = &DynamicMethod<T, S, C, Event>> {
34        self.handlers
35            .iter()
36            .filter(move |(events, _)| events.contains(event))
37            .map(|(_, handler)| handler)
38    }
39}
40
41impl<T: PickerItem, S: Selection, C> InterruptHandlers<T, S, C> {
42    pub fn new() -> Self {
43        Self { handlers: vec![] }
44    }
45
46    pub fn set(&mut self, variant: Interrupt, handler: DynamicMethod<T, S, C, Interrupt>) {
47        if let Some((_, handlers)) = self.handlers.iter_mut().find(|(v, _)| *v == variant) {
48            handlers.push(handler);
49        } else {
50            self.handlers.push((variant, vec![handler]));
51        }
52    }
53
54    pub fn get(&self, variant: &Interrupt) -> impl Iterator<Item = &DynamicMethod<T, S, C, Interrupt>> {
55        self.handlers
56            .iter()
57            .filter_map(move |(v, h)| (v == variant).then_some(h))
58            .flatten()
59    }
60}
61
62// ----------------------------------------------------------------------------------------
63
64impl<T: PickerItem, S: Selection, C> fmt::Debug for EventHandlers<T, S, C> {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        f.debug_struct("EventHandlers")
67            .field("handler_count", &self.handlers.len())
68            .finish()
69    }
70}
71
72impl<T: PickerItem, S: Selection, C> fmt::Debug for InterruptHandlers<T, S, C> {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        f.debug_struct("InterruptHandlers")
75            .field("variant_count", &self.handlers.len())
76            .finish()
77    }
78}