event_notify/
event.rs

1trait ListenFn<P, N, R>: 'static + Send + Sync + Fn(P, Option<&N>) -> R {}
2
3impl<T, P, N, R> ListenFn<P, N, R> for T
4    where
5        T: 'static + ?Sized + Send + Sync + Fn(P, Option<&N>) -> R,
6{}
7
8pub struct Event<P, R> {
9    l: Listen<P, R>,
10}
11
12impl<P, R> Event<P, R> {
13    #[inline]
14    pub fn listen<F>(f: F) -> Listen<P, R>
15        where
16            F: Fn(P, Option<&Next<P, R>>) -> R + Send + Sync + 'static,
17    {
18        Listen::new(f)
19    }
20
21    #[inline]
22    pub fn fire(&self, args: P) -> R {
23        let n = self.l.next.as_ref().map(|n| n.as_ref());
24        (self.l.f)(args, n)
25    }
26}
27
28pub struct Next<P, R> {
29    l: Listen<P, R>,
30}
31
32impl<P, R> Next<P, R> {
33    #[inline]
34    fn new(l: Listen<P, R>) -> Self {
35        Self {
36            l,
37        }
38    }
39
40    #[inline]
41    pub fn forward(&self, args: P) -> R {
42        let n = self.l.next.as_ref().map(|n| n.as_ref());
43        (self.l.f)(args, n)
44    }
45
46    #[inline]
47    fn link(&mut self, next: Self) {
48        if let Some(n) = self.l.next.as_mut() {
49            n.link(next);
50        } else {
51            self.l.next = Some(Box::new(next));
52        }
53    }
54}
55
56pub struct Listen<P, R> {
57    f: Box<dyn ListenFn<P, Next<P, R>, R>>,
58    next: Option<Box<Next<P, R>>>,
59}
60
61impl<P, R> Listen<P, R>
62{
63    #[inline]
64    fn new<F>(f: F) -> Self
65        where
66            F: Fn(P, Option<&Next<P, R>>) -> R + Send + Sync + 'static,
67    {
68        Self {
69            f: Box::new(f),
70            next: None,
71        }
72    }
73
74    #[inline]
75    pub fn listen<F>(mut self, f: F) -> Self
76        where
77            F: Fn(P, Option<&Next<P, R>>) -> R + Send + Sync + 'static,
78    {
79        let next = Next::new(Self::new(f));
80        if let Some(n) = self.next.as_mut() {
81            n.link(next);
82        } else {
83            self.next = Some(Box::new(next));
84        }
85        self
86    }
87
88    #[inline]
89    pub fn finish(self) -> Event<P, R> {
90        Event { l: self }
91    }
92}
93
94
95#[test]
96fn test_event() {
97    let simple1 = Event::<i32, i32>::listen(|args: i32, next| {
98        if args == 100 {
99            return args;
100        }
101        if let Some(next) = next {
102            next.forward(args)
103        } else {
104            1 * args
105        }
106    })
107        .listen(|args: i32, next| {
108            if args == 200 {
109                return args;
110            }
111            if let Some(next) = next {
112                next.forward(args)
113            } else {
114                2 * args
115            }
116        })
117        .listen(|args: i32, next| {
118            if args == 300 {
119                return args;
120            }
121            if let Some(next) = next {
122                next.forward(args)
123            } else {
124                3 * args
125            }
126        })
127        .finish();
128
129    assert_eq!(simple1.fire(10), 30);
130    assert_eq!(simple1.fire(100), 100);
131    assert_eq!(simple1.fire(300), 300);
132}
133
134
135
136
137
138
139