1use crate::experimental::clock::Timed;
6use crate::experimental::event::Event;
7
8pub trait IntoReactor<T, S = ()> {
19 type Reactor: Reactor<T, S>;
20
21 fn into_reactor(self) -> Self::Reactor;
22}
23
24pub trait Reactor<T, S = ()> {
34 type Response;
36 type Error;
38
39 fn react(
49 &mut self,
50 event: Timed<Event<T>>,
51 context: Context<'_, S>,
52 ) -> Result<Self::Response, Self::Error>;
53
54 fn map_response<P, F>(self, f: F) -> MapResponse<Self, F>
55 where
56 Self: Sized,
57 F: FnMut(Self::Response) -> P,
58 {
59 MapResponse { reactor: self, f }
60 }
61
62 fn map_error<E, F>(self, f: F) -> MapError<Self, F>
63 where
64 Self: Sized,
65 F: FnMut(Self::Error) -> E,
66 {
67 MapError { reactor: self, f }
68 }
69
70 fn respond<P>(self, response: P) -> Respond<Self, P>
73 where
74 Self: Sized,
75 P: Clone,
76 {
77 Respond { reactor: self, response }
78 }
79
80 fn fail<E>(self, error: E) -> Fail<Self, E>
83 where
84 Self: Sized,
85 E: Clone,
86 {
87 Fail { reactor: self, error }
88 }
89
90 fn then<R>(self, reactor: R) -> Then<Self, R>
97 where
98 Self: Sized,
99 T: Clone,
100 R: Reactor<T, S>,
101 {
102 Then { reactor: self, then: reactor }
103 }
104
105 fn and<R>(self, reactor: R) -> And<Self, R>
113 where
114 Self: Sized,
115 Self::Error: From<R::Error>,
116 T: Clone,
117 R: Reactor<T, S>,
118 {
119 And { reactor: self, and: reactor }
120 }
121
122 fn or<R>(self, reactor: R) -> Or<Self, R>
130 where
131 Self: Sized,
132 T: Clone,
133 R: Reactor<T, S, Response = Self::Response>,
134 {
135 Or { reactor: self, or: reactor }
136 }
137
138 fn inspect<F>(self, f: F) -> impl Reactor<T, S, Response = Self::Response, Error = Self::Error>
141 where
142 Self: Sized,
143 T: Clone,
144 F: FnMut(&Timed<Event<T>>, &Result<Self::Response, Self::Error>),
145 {
146 Inspect { reactor: self, f }
147 }
148}
149
150impl<T, S, R, E, F> Reactor<T, S> for F
151where
152 F: FnMut(Timed<Event<T>>, Context<'_, S>) -> Result<R, E>,
153{
154 type Response = R;
155 type Error = E;
156
157 fn react(
158 &mut self,
159 event: Timed<Event<T>>,
160 context: Context<'_, S>,
161 ) -> Result<Self::Response, Self::Error> {
162 (self)(event, context)
163 }
164}
165
166#[derive(Debug)]
167pub struct Context<'s, S = ()> {
168 pub state: &'s mut S,
169}
170
171impl<'s, S> Context<'s, S> {
172 pub fn from_state(state: &'s mut S) -> Self {
173 Context { state }
174 }
175
176 pub fn with_state<'q, U>(self, state: &'q mut U) -> Context<'q, U> {
177 Context { state }
178 }
179
180 pub fn reborrow<'q>(&'q mut self) -> Context<'q, S>
188 where
189 's: 'q,
190 {
191 Context { state: self.state }
192 }
193}
194
195#[derive(Clone, Copy, Debug)]
199#[repr(transparent)]
200pub struct OnDataRecord<R> {
201 reactor: R,
202}
203
204impl<T, S, R> Reactor<T, S> for OnDataRecord<R>
205where
206 R: Reactor<T, S>,
207{
208 type Response = R::Response;
209 type Error = R::Error;
210
211 #[inline(always)]
212 fn react(
213 &mut self,
214 event: Timed<Event<T>>,
215 context: Context<'_, S>,
216 ) -> Result<Self::Response, Self::Error> {
217 self.reactor.react(event, context)
218 }
219}
220
221#[derive(Clone, Copy, Debug)]
222pub struct MapResponse<R, F> {
223 reactor: R,
224 f: F,
225}
226
227impl<T, S, R, O, F> Reactor<T, S> for MapResponse<R, F>
228where
229 R: Reactor<T, S>,
230 F: FnMut(R::Response) -> O,
231{
232 type Response = O;
233 type Error = R::Error;
234
235 fn react(
236 &mut self,
237 event: Timed<Event<T>>,
238 context: Context<'_, S>,
239 ) -> Result<Self::Response, Self::Error> {
240 self.reactor.react(event, context).map(|response| (self.f)(response))
241 }
242}
243
244#[derive(Clone, Copy, Debug)]
245pub struct MapError<R, F> {
246 reactor: R,
247 f: F,
248}
249
250impl<T, S, R, O, F> Reactor<T, S> for MapError<R, F>
251where
252 R: Reactor<T, S>,
253 F: FnMut(R::Error) -> O,
254{
255 type Response = R::Response;
256 type Error = O;
257
258 fn react(
259 &mut self,
260 event: Timed<Event<T>>,
261 context: Context<'_, S>,
262 ) -> Result<Self::Response, Self::Error> {
263 self.reactor.react(event, context).map_err(|error| (self.f)(error))
264 }
265}
266
267#[derive(Clone, Copy, Debug)]
268pub struct MapDataRecord<R, F> {
269 reactor: R,
270 f: F,
271}
272
273impl<U, S, R, O, F> Reactor<U, S> for MapDataRecord<R, F>
274where
275 R: Reactor<O, S>,
276 F: FnMut(U, Context<'_, S>) -> O,
277{
278 type Response = R::Response;
279 type Error = R::Error;
280
281 fn react(
282 &mut self,
283 event: Timed<Event<U>>,
284 mut context: Context<'_, S>,
285 ) -> Result<Self::Response, Self::Error> {
286 let event = event.map_data_record(|record| (self.f)(record, context.reborrow()));
287 self.reactor.react(event, context)
288 }
289}
290
291#[derive(Clone, Copy, Debug)]
292pub struct FilterMapDataRecord<R, F> {
293 reactor: R,
294 f: F,
295}
296
297impl<U, S, R, O, F> Reactor<U, S> for FilterMapDataRecord<R, F>
298where
299 R: Reactor<O, S>,
300 F: FnMut(U, Context<'_, S>) -> Option<O>,
301{
302 type Response = Option<R::Response>;
303 type Error = R::Error;
304
305 fn react(
306 &mut self,
307 event: Timed<Event<U>>,
308 mut context: Context<'_, S>,
309 ) -> Result<Self::Response, Self::Error> {
310 event
311 .filter_map_data_record(|record| (self.f)(record, context.reborrow()))
312 .map(|event| self.reactor.react(event, context.reborrow()))
313 .transpose()
314 }
315}
316
317#[derive(Clone, Copy, Debug)]
318pub struct WithState<R, S> {
319 reactor: R,
320 state: S,
321}
322
323impl<T, S, U, R> Reactor<T, U> for WithState<R, S>
324where
325 R: Reactor<T, S>,
326{
327 type Response = R::Response;
328 type Error = R::Error;
329
330 fn react(
331 &mut self,
332 event: Timed<Event<T>>,
333 context: Context<'_, U>,
334 ) -> Result<Self::Response, Self::Error> {
335 self.reactor.react(event, context.with_state(&mut self.state))
336 }
337}
338
339#[derive(Clone, Copy, Debug)]
340pub struct MapState<R, F> {
341 reactor: R,
342 f: F,
343}
344
345impl<T, S, U, R, F> Reactor<T, S> for MapState<R, F>
346where
347 R: Reactor<T, U>,
348 F: FnMut(&mut S) -> U,
349{
350 type Response = R::Response;
351 type Error = R::Error;
352
353 fn react(
354 &mut self,
355 event: Timed<Event<T>>,
356 context: Context<'_, S>,
357 ) -> Result<Self::Response, Self::Error> {
358 let mut state = (self.f)(context.state);
359 self.reactor.react(event, context.with_state(&mut state))
360 }
361}
362
363#[derive(Clone, Copy, Debug)]
364pub struct Respond<R, P> {
365 reactor: R,
366 response: P,
367}
368
369impl<T, S, P, R> Reactor<T, S> for Respond<R, P>
370where
371 P: Clone,
372 R: Reactor<T, S>,
373{
374 type Response = P;
375 type Error = R::Error;
376
377 fn react(
378 &mut self,
379 event: Timed<Event<T>>,
380 context: Context<'_, S>,
381 ) -> Result<Self::Response, Self::Error> {
382 let _ = self.reactor.react(event, context);
383 Ok(self.response.clone())
384 }
385}
386
387#[derive(Clone, Copy, Debug)]
388pub struct Fail<R, E> {
389 reactor: R,
390 error: E,
391}
392
393impl<T, S, E, R> Reactor<T, S> for Fail<R, E>
394where
395 E: Clone,
396 R: Reactor<T, S>,
397{
398 type Response = R::Response;
399 type Error = E;
400
401 fn react(
402 &mut self,
403 event: Timed<Event<T>>,
404 context: Context<'_, S>,
405 ) -> Result<Self::Response, Self::Error> {
406 let _ = self.reactor.react(event, context);
407 Err(self.error.clone())
408 }
409}
410
411#[derive(Clone, Copy, Debug)]
412pub struct Then<R1, R2> {
413 reactor: R1,
414 then: R2,
415}
416
417impl<T, S, R1, R2> Reactor<T, S> for Then<R1, R2>
418where
419 T: Clone,
420 R1: Reactor<T, S>,
421 R2: Reactor<T, S>,
422{
423 type Response = R2::Response;
424 type Error = R2::Error;
425
426 fn react(
427 &mut self,
428 event: Timed<Event<T>>,
429 mut context: Context<'_, S>,
430 ) -> Result<Self::Response, Self::Error> {
431 let _ = self.reactor.react(event.clone(), context.reborrow());
432 self.then.react(event, context)
433 }
434}
435
436#[derive(Clone, Copy, Debug)]
437pub struct And<R1, R2> {
438 reactor: R1,
439 and: R2,
440}
441
442impl<T, S, R1, R2> Reactor<T, S> for And<R1, R2>
443where
444 T: Clone,
445 R1: Reactor<T, S>,
446 R1::Error: From<R2::Error>,
447 R2: Reactor<T, S>,
448{
449 type Response = R2::Response;
450 type Error = R1::Error;
451
452 fn react(
453 &mut self,
454 event: Timed<Event<T>>,
455 mut context: Context<'_, S>,
456 ) -> Result<Self::Response, Self::Error> {
457 self.reactor
458 .react(event.clone(), context.reborrow())
459 .and_then(|_| self.and.react(event, context.reborrow()).map_err(From::from))
460 }
461}
462
463#[derive(Clone, Copy, Debug)]
464pub struct Or<R1, R2> {
465 reactor: R1,
466 or: R2,
467}
468
469impl<T, S, R1, R2> Reactor<T, S> for Or<R1, R2>
470where
471 T: Clone,
472 R1: Reactor<T, S>,
473 R2: Reactor<T, S, Response = R1::Response>,
474{
475 type Response = R1::Response;
476 type Error = R2::Error;
477
478 fn react(
479 &mut self,
480 event: Timed<Event<T>>,
481 mut context: Context<'_, S>,
482 ) -> Result<Self::Response, Self::Error> {
483 match self.reactor.react(event.clone(), context.reborrow()) {
484 Ok(response) => Ok(response),
485 Err(_) => self.or.react(event, context.reborrow()),
486 }
487 }
488}
489
490#[derive(Clone, Copy, Debug)]
491pub struct Inspect<R, F> {
492 reactor: R,
493 f: F,
494}
495
496impl<T, S, R, F> Reactor<T, S> for Inspect<R, F>
497where
498 T: Clone,
499 R: Reactor<T, S>,
500 F: FnMut(&Timed<Event<T>>, &Result<R::Response, R::Error>),
501{
502 type Response = R::Response;
503 type Error = R::Error;
504
505 fn react(
506 &mut self,
507 event: Timed<Event<T>>,
508 mut context: Context<'_, S>,
509 ) -> Result<Self::Response, Self::Error> {
510 let output = self.reactor.react(event.clone(), context.reborrow());
511 (self.f)(&event, &output);
512 output
513 }
514}
515
516#[derive(Clone, Copy, Debug)]
536#[repr(transparent)]
537pub struct Dynamic<R>(R);
538
539#[derive(Clone, Copy, Debug)]
545#[repr(transparent)]
546pub struct ThenChain<R>(R);
547
548impl<T, S, R> IntoReactor<T, S> for ThenChain<Vec<R>>
549where
550 T: Clone,
551 R: Reactor<T, S>,
552{
553 type Reactor = ThenChain<Dynamic<Vec<R>>>;
554
555 fn into_reactor(self) -> Self::Reactor {
556 ThenChain(Dynamic(self.0))
557 }
558}
559
560impl<T, S, R> Reactor<T, S> for ThenChain<Dynamic<Vec<R>>>
561where
562 T: Clone,
563 R: Reactor<T, S>,
564{
565 type Response = R::Response;
566 type Error = R::Error;
567
568 fn react(
569 &mut self,
570 event: Timed<Event<T>>,
571 mut context: Context<'_, S>,
572 ) -> Result<Self::Response, Self::Error> {
573 self.0
574 .0
575 .iter_mut()
576 .map(|reactor| reactor.react(event.clone(), context.reborrow()))
577 .next_back()
578 .expect("empty `then` combinator")
579 }
580}
581
582#[derive(Clone, Copy, Debug)]
588#[repr(transparent)]
589pub struct AndChain<R>(R);
590
591impl<T, S, R> IntoReactor<T, S> for AndChain<Vec<R>>
592where
593 T: Clone,
594 R: Reactor<T, S>,
595{
596 type Reactor = AndChain<Dynamic<Vec<R>>>;
597
598 fn into_reactor(self) -> Self::Reactor {
599 AndChain(Dynamic(self.0))
600 }
601}
602
603impl<T, S, R> Reactor<T, S> for AndChain<Dynamic<Vec<R>>>
604where
605 T: Clone,
606 R: Reactor<T, S>,
607{
608 type Response = Vec<R::Response>;
609 type Error = R::Error;
610
611 fn react(
612 &mut self,
613 event: Timed<Event<T>>,
614 mut context: Context<'_, S>,
615 ) -> Result<Self::Response, Self::Error> {
616 self.0
617 .0
618 .iter_mut()
619 .map(|reactor| reactor.react(event.clone(), context.reborrow()))
620 .collect()
621 }
622}
623
624#[derive(Clone, Copy, Debug)]
630#[repr(transparent)]
631pub struct OrChain<R>(R);
632
633impl<T, S, R> IntoReactor<T, S> for OrChain<Vec<R>>
634where
635 T: Clone,
636 R: Reactor<T, S>,
637{
638 type Reactor = OrChain<Dynamic<Vec<R>>>;
639
640 fn into_reactor(self) -> Self::Reactor {
641 OrChain(Dynamic(self.0))
642 }
643}
644
645impl<T, S, R> Reactor<T, S> for OrChain<Dynamic<Vec<R>>>
646where
647 T: Clone,
648 R: Reactor<T, S>,
649{
650 type Response = R::Response;
651 type Error = R::Error;
652
653 fn react(
654 &mut self,
655 event: Timed<Event<T>>,
656 mut context: Context<'_, S>,
657 ) -> Result<Self::Response, Self::Error> {
658 let mut outputs =
659 self.0 .0.iter_mut().map(|reactor| reactor.react(event.clone(), context.reborrow()));
660 let error = outputs.by_ref().take_while(Result::is_err).last();
661 outputs.next().or(error).expect("empty `or` combinator")
662 }
663}
664
665pub fn on_data_record<T, R>(reactor: R) -> OnDataRecord<R>
675where
676 R: Reactor<T, ()>,
677{
678 OnDataRecord { reactor }
679}
680
681pub fn respond<T, S, P, R>(response: P, reactor: R) -> Respond<R, P>
682where
683 P: Clone,
684 R: Reactor<T, S>,
685{
686 reactor.respond(response)
687}
688
689pub fn fail<T, S, E, R>(error: E, reactor: R) -> Fail<R, E>
690where
691 E: Clone,
692 R: Reactor<T, S>,
693{
694 reactor.fail(error)
695}
696
697pub fn map_data_record<T, S, O, F, R>(f: F, reactor: R) -> MapDataRecord<R, F>
698where
699 F: FnMut(T, Context<'_, S>) -> O,
700 R: Reactor<O, S>,
701{
702 MapDataRecord { reactor, f }
703}
704
705pub fn filter_map_data_record<T, U, S, O, F, R>(f: F, reactor: R) -> FilterMapDataRecord<R, F>
706where
707 F: FnMut(T, Context<'_, S>) -> Option<O>,
708 R: Reactor<U, S>,
709{
710 FilterMapDataRecord { reactor, f }
711}
712
713pub fn with_state<T, S, R>(state: S, reactor: R) -> WithState<R, S>
714where
715 R: Reactor<T, S>,
716{
717 WithState { reactor, state }
718}
719
720pub fn map_state<T, S, O, F, R>(f: F, reactor: R) -> MapState<R, F>
721where
722 F: FnMut(&mut S) -> O,
723 R: Reactor<T, O>,
724{
725 MapState { reactor, f }
726}
727
728pub fn then<T, S, R>(reactors: R) -> <ThenChain<R> as IntoReactor<T, S>>::Reactor
742where
743 ThenChain<R>: IntoReactor<T, S>,
744 T: Clone,
745{
746 ThenChain(reactors).into_reactor()
747}
748
749pub fn and<T, S, R>(reactors: R) -> <AndChain<R> as IntoReactor<T, S>>::Reactor
763where
764 AndChain<R>: IntoReactor<T, S>,
765 T: Clone,
766{
767 AndChain(reactors).into_reactor()
768}
769
770pub fn or<T, S, R>(reactors: R) -> <OrChain<R> as IntoReactor<T, S>>::Reactor
784where
785 OrChain<R>: IntoReactor<T, S>,
786 T: Clone,
787{
788 OrChain(reactors).into_reactor()
789}
790
791macro_rules! with_nonunary_tuples {
798 ($f:ident, ( $head:ident, $tail:ident $(,)? ) $(,)?) => {
799 $f!(($head, $tail));
800 };
801 ($f:ident, ( $head:ident, $body:ident, $($tail:ident), +$(,)? ) $(,)?) => {
802 $f!(($head,$body,$($tail,)*));
803 with_nonunary_tuples!($f, ( $body,$($tail,)+ ));
804 };
805}
806
807macro_rules! with_reactor_combinator_chain_tuples {
809 ($f:ident) => {
810 with_nonunary_tuples!($f, (T1, T2, T3, T4, T5, T6, T7, T8));
812 };
813}
814
815macro_rules! reverse_combinator_chain_tuple_output_type {
820 ($combinator:ident, ( $head:ident,$body:ident,$($tail:ident,)+ )$(,)?) => {
821 $combinator<reverse_combinator_chain_tuple_output_type!($combinator, ($body,$($tail,)+)), $head>
822 };
823 ($combinator:ident, ( $head:ident,$tail:ident$(,)? )$(,)?) => {
824 $combinator<$tail, $head>
825 };
826}
827
828macro_rules! forward_combinator_chain_tuple_output_type {
834 ($combinator:ident, ( $($forward:ident),*$(,)? )) => {
835 forward_combinator_chain_tuple_output_type!($combinator, ($($forward,)*); ())
836 };
837 ($combinator:ident, ( $head:ident,$($tail:ident),*$(,)? ); ( $($reverse:ident),*$(,)? )) => {
838 forward_combinator_chain_tuple_output_type!($combinator, ($($tail,)*); ($head,$($reverse,)*))
839 };
840 ($combinator:ident, ( $(,)? ); ( $($reverse:ident),*$(,)? )) => {
843 reverse_combinator_chain_tuple_output_type!($combinator, ( $($reverse,)* ))
844 };
845}
846
847macro_rules! impl_into_reactor_for_then_chain_tuple {
852 (( $head:ident, $($tail:ident $(,)?)+ )) => {
853 impl<T, S, $head $(,$tail)+> IntoReactor<T, S> for ThenChain<($head $(,$tail)+)>
854 where
855 T: Clone,
856 $head: Reactor<T, S>,
857 $(
858 $tail: Reactor<T, S, Response = $head::Response>,
859 $head::Error: From<$tail::Error>,
860 )+
861 {
862 type Reactor = forward_combinator_chain_tuple_output_type!(Then, ($head $(,$tail)+));
863
864 #[allow(non_snake_case)]
865 #[allow(unused_assignments)]
866 fn into_reactor(self) -> Self::Reactor {
867 let ($head $(, $tail)+) = self.0;
868 $head
869 $(
870 .then($tail)
871 )+
872 }
873 }
874 }
875}
876with_reactor_combinator_chain_tuples!(impl_into_reactor_for_then_chain_tuple);
877
878macro_rules! impl_into_reactor_for_and_chain_tuple {
883 (( $head:ident, $($tail:ident $(,)?)+ )) => {
884 impl<T, S, $head $(,$tail)+> IntoReactor<T, S> for AndChain<($head $(,$tail)+)>
885 where
886 T: Clone,
887 $head: Reactor<T, S>,
888 $(
889 $tail: Reactor<T, S>,
890 $head::Error: From<$tail::Error>,
891 )+
892 {
893 type Reactor = forward_combinator_chain_tuple_output_type!(And, ($head $(,$tail)+));
894
895 #[allow(non_snake_case)]
896 #[allow(unused_assignments)]
897 fn into_reactor(self) -> Self::Reactor {
898 let ($head $(, $tail)+) = self.0;
899 $head
900 $(
901 .and($tail)
902 )+
903 }
904 }
905 }
906}
907with_reactor_combinator_chain_tuples!(impl_into_reactor_for_and_chain_tuple);
908
909macro_rules! impl_into_reactor_for_or_chain_tuple {
914 (( $head:ident, $($tail:ident $(,)?)+ )) => {
915 impl<T, S, $head $(,$tail)+> IntoReactor<T, S> for OrChain<($head $(,$tail)+)>
916 where
917 T: Clone,
918 $head: Reactor<T, S>,
919 $(
920 $tail: Reactor<T, S, Response = $head::Response>,
921 $head::Error: From<$tail::Error>,
922 )+
923 {
924 type Reactor = forward_combinator_chain_tuple_output_type!(Or, ($head $(,$tail)+));
925
926 #[allow(non_snake_case)]
927 #[allow(unused_assignments)]
928 fn into_reactor(self) -> Self::Reactor {
929 let ($head $(, $tail)+) = self.0;
930 $head
931 $(
932 .or($tail)
933 )+
934 }
935 }
936 }
937}
938with_reactor_combinator_chain_tuples!(impl_into_reactor_for_or_chain_tuple);