1pub use prototty_input;
2pub use prototty_input::Input;
3pub use prototty_render;
4pub use prototty_render::{ColModify, Frame, View, ViewContext};
5use std::marker::PhantomData;
6use std::time::Duration;
7
8mod app;
9pub mod common_event;
10pub use app::*;
11
12pub enum Handled<R, C> {
13 Return(R),
14 Continue(C),
15}
16
17impl<R, C> Handled<R, C> {
18 pub fn map_continue<D, F>(self, f: F) -> Handled<R, D>
19 where
20 F: FnOnce(C) -> D,
21 {
22 match self {
23 Handled::Return(r) => Handled::Return(r),
24 Handled::Continue(c) => Handled::Continue(f(c)),
25 }
26 }
27 pub fn map_return<S, F>(self, f: F) -> Handled<S, C>
28 where
29 F: FnOnce(R) -> S,
30 {
31 match self {
32 Handled::Return(r) => Handled::Return(f(r)),
33 Handled::Continue(c) => Handled::Continue(c),
34 }
35 }
36}
37
38pub trait EventOrPeek: Sized + private::Sealed {
39 type Event;
40 fn with<A, X, F, G>(self, arg: A, f: F, g: G) -> X
41 where
42 F: FnOnce(A, Self::Event) -> X,
43 G: FnOnce(A) -> X;
44}
45
46pub fn event_or_peek_with_handled<EP, A, X, F>(event_or_peek: EP, arg: A, f: F) -> Handled<X, A>
47where
48 EP: EventOrPeek,
49 F: FnOnce(A, EP::Event) -> Handled<X, A>,
50{
51 event_or_peek.with(arg, f, Handled::Continue)
52}
53
54pub struct Event<E>(E);
55pub struct Peek<E>(PhantomData<E>);
56
57impl<E> Event<E> {
58 pub fn new(e: E) -> Self {
59 Self(e)
60 }
61}
62
63impl<E> Peek<E> {
64 pub fn new() -> Self {
65 Self(PhantomData)
66 }
67}
68
69impl<E> Default for Peek<E> {
70 fn default() -> Self {
71 Self::new()
72 }
73}
74
75impl<E> EventOrPeek for Event<E> {
76 type Event = E;
77 fn with<A, X, F, G>(self, arg: A, f: F, _g: G) -> X
78 where
79 F: FnOnce(A, Self::Event) -> X,
80 G: FnOnce(A) -> X,
81 {
82 f(arg, self.0)
83 }
84}
85
86impl<E> EventOrPeek for Peek<E> {
87 type Event = E;
88 fn with<A, X, F, G>(self, arg: A, _f: F, g: G) -> X
89 where
90 F: FnOnce(A, Self::Event) -> X,
91 G: FnOnce(A) -> X,
92 {
93 g(arg)
94 }
95}
96
97mod private {
98 pub trait Sealed {}
99 impl<E> Sealed for super::Event<E> {}
100 impl<E> Sealed for super::Peek<E> {}
101}
102
103pub trait EventRoutine: Sized {
104 type Return;
105 type Data;
106 type View;
107 type Event;
108
109 fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, event_or_peek: EP) -> Handled<Self::Return, Self>
110 where
111 EP: EventOrPeek<Event = Self::Event>;
112
113 fn view<F, C>(&self, data: &Self::Data, view: &mut Self::View, context: ViewContext<C>, frame: &mut F)
114 where
115 F: Frame,
116 C: ColModify;
117
118 fn repeat<U, F>(self, f: F) -> Repeat<Self, F>
119 where
120 F: FnMut(Self::Return) -> Handled<U, Self>,
121 {
122 Repeat { t: self, f }
123 }
124
125 fn select<S>(self, selector: S) -> Select<Self, S>
126 where
127 S: Selector<DataOutput = Self::Data, ViewOutput = Self::View>,
128 {
129 Select { t: self, selector }
130 }
131
132 fn and_then<U, F>(self, f: F) -> AndThen<Self, U, F>
133 where
134 U: EventRoutine<Data = Self::Data, View = Self::View>,
135 F: FnOnce(Self::Return) -> U,
136 {
137 AndThen(AndThenPrivate::First { t: self, f })
138 }
139
140 fn map<F, U>(self, f: F) -> Map<Self, F>
141 where
142 F: FnOnce(Self::Return) -> U,
143 {
144 Map { t: self, f }
145 }
146
147 fn convert_input_to_common_event(self) -> common_event::ConvertInputToCommonEvent<Self> {
148 common_event::ConvertInputToCommonEvent(self)
149 }
150
151 fn app_one_shot_ignore_return(
152 self,
153 data: Self::Data,
154 view: Self::View,
155 ) -> EventRoutineAppOneShotIgnoreReturn<Self> {
156 EventRoutineAppOneShotIgnoreReturn::new(self, data, view)
157 }
158
159 fn return_on_exit<F>(self, f: F) -> common_event::ReturnOnExit<Self, F>
160 where
161 F: FnOnce(&mut Self::Data) -> Self::Return,
162 {
163 common_event::ReturnOnExit { t: self, f }
164 }
165
166 fn decorated<D>(self, d: D) -> Decorated<Self, D>
167 where
168 D: Decorate<View = Self::View, Data = Self::Data>,
169 {
170 Decorated { t: self, d }
171 }
172
173 fn on_event<F>(self, f: F) -> OnEvent<Self, F>
174 where
175 F: FnMut(&mut &mut Self::Data, &Self::Event),
176 {
177 OnEvent { t: self, f }
178 }
179}
180
181struct OneShot<T, D, V, E> {
182 field: T,
183 data: PhantomData<D>,
184 view: PhantomData<V>,
185 event: PhantomData<E>,
186}
187
188impl<T, D, V, E> OneShot<T, D, V, E> {
189 pub fn new(field: T) -> Self {
190 Self {
191 field,
192 data: PhantomData,
193 view: PhantomData,
194 event: PhantomData,
195 }
196 }
197}
198
199pub struct Value<T, D, V, E>(OneShot<T, D, V, E>);
200
201impl<T, D, V, E> Value<T, D, V, E> {
202 pub fn new(value: T) -> Self {
203 Self(OneShot::new(value))
204 }
205}
206
207impl<T, D, V, E> EventRoutine for Value<T, D, V, E> {
208 type Return = T;
209 type Data = D;
210 type View = V;
211 type Event = E;
212
213 fn handle<EP>(self, _data: &mut Self::Data, _view: &Self::View, _event_or_peek: EP) -> Handled<Self::Return, Self>
214 where
215 EP: EventOrPeek<Event = Self::Event>,
216 {
217 Handled::Return(self.0.field)
218 }
219
220 fn view<F, C>(&self, _data: &Self::Data, _view: &mut Self::View, _context: ViewContext<C>, _frame: &mut F)
221 where
222 F: Frame,
223 C: ColModify,
224 {
225 }
226}
227
228pub struct SideEffect<F, D, V, E>(OneShot<F, D, V, E>);
229
230impl<F, D, V, E> SideEffect<F, D, V, E> {
231 pub fn new(f: F) -> Self {
232 Self(OneShot::new(f))
233 }
234}
235
236impl<F, D, V, E, T> EventRoutine for SideEffect<F, D, V, E>
237where
238 F: FnOnce(&mut D, &V) -> T,
239{
240 type Return = T;
241 type Data = D;
242 type View = V;
243 type Event = E;
244
245 fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, _event_or_peek: EP) -> Handled<Self::Return, Self>
246 where
247 EP: EventOrPeek<Event = Self::Event>,
248 {
249 Handled::Return((self.0.field)(data, view))
250 }
251
252 fn view<G, C>(&self, _data: &Self::Data, _view: &mut Self::View, _context: ViewContext<C>, _frame: &mut G)
253 where
254 G: Frame,
255 C: ColModify,
256 {
257 }
258}
259
260enum SideEffectThenPrivate<F, D, V, E, U> {
261 First(OneShot<F, D, V, E>),
262 Second(U),
263}
264pub struct SideEffectThen<F, D, V, E, U>(SideEffectThenPrivate<F, D, V, E, U>);
265
266impl<F, D, V, E, U> SideEffectThen<F, D, V, E, U>
267where
268 U: EventRoutine<Data = D, View = V, Event = E>,
269 F: FnOnce(&mut D, &V) -> U,
270{
271 pub fn new(f: F) -> Self {
272 Self(SideEffectThenPrivate::First(OneShot::new(f)))
273 }
274}
275
276impl<F, D, V, E, U> EventRoutine for SideEffectThen<F, D, V, E, U>
277where
278 U: EventRoutine<Data = D, View = V, Event = E>,
279 F: FnOnce(&mut D, &V) -> U,
280{
281 type Return = U::Return;
282 type Data = D;
283 type View = V;
284 type Event = E;
285
286 fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, event_or_peek: EP) -> Handled<Self::Return, Self>
287 where
288 EP: EventOrPeek<Event = Self::Event>,
289 {
290 match self.0 {
291 SideEffectThenPrivate::First(one_shot) => (one_shot.field)(data, view)
292 .handle(data, view, Peek::new())
293 .map_continue(|u| SideEffectThen(SideEffectThenPrivate::Second(u))),
294 SideEffectThenPrivate::Second(u) => u
295 .handle(data, view, event_or_peek)
296 .map_continue(|u| SideEffectThen(SideEffectThenPrivate::Second(u))),
297 }
298 }
299
300 fn view<G, C>(&self, data: &Self::Data, view: &mut Self::View, context: ViewContext<C>, frame: &mut G)
301 where
302 G: Frame,
303 C: ColModify,
304 {
305 match self.0 {
306 SideEffectThenPrivate::First(_) => (),
307 SideEffectThenPrivate::Second(ref u) => u.view(data, view, context, frame),
308 }
309 }
310}
311
312pub struct Map<T, F> {
313 t: T,
314 f: F,
315}
316
317impl<T, U, F> EventRoutine for Map<T, F>
318where
319 T: EventRoutine,
320 F: FnOnce(T::Return) -> U,
321{
322 type Return = U;
323 type Data = T::Data;
324 type View = T::View;
325 type Event = T::Event;
326
327 fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, event_or_peek: EP) -> Handled<Self::Return, Self>
328 where
329 EP: EventOrPeek<Event = Self::Event>,
330 {
331 let Self { t, f } = self;
332 match t.handle(data, view, event_or_peek) {
333 Handled::Continue(t) => Handled::Continue(Self { t, f }),
334 Handled::Return(r) => Handled::Return(f(r)),
335 }
336 }
337
338 fn view<G, C>(&self, data: &Self::Data, view: &mut Self::View, context: ViewContext<C>, frame: &mut G)
339 where
340 G: Frame,
341 C: ColModify,
342 {
343 self.t.view(data, view, context, frame)
344 }
345}
346
347enum AndThenPrivate<T, U, F> {
348 First { t: T, f: F },
349 Second(U),
350}
351
352pub struct AndThen<T, U, F>(AndThenPrivate<T, U, F>);
353
354impl<T, U, F> EventRoutine for AndThen<T, U, F>
355where
356 T: EventRoutine,
357 U: EventRoutine<Data = T::Data, View = T::View, Event = T::Event>,
358 F: FnOnce(T::Return) -> U,
359{
360 type Return = U::Return;
361 type Data = T::Data;
362 type View = T::View;
363 type Event = T::Event;
364
365 fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, event_or_peek: EP) -> Handled<Self::Return, Self>
366 where
367 EP: EventOrPeek<Event = Self::Event>,
368 {
369 match self.0 {
370 AndThenPrivate::First { t, f } => match t.handle(data, view, event_or_peek) {
371 Handled::Continue(t) => Handled::Continue(AndThen(AndThenPrivate::First { t, f })),
372 Handled::Return(r) => f(r)
373 .handle(data, view, Peek::new())
374 .map_continue(|u| AndThen(AndThenPrivate::Second(u))),
375 },
376 AndThenPrivate::Second(u) => u
377 .handle(data, view, event_or_peek)
378 .map_continue(|u| AndThen(AndThenPrivate::Second(u))),
379 }
380 }
381
382 fn view<G, C>(&self, data: &Self::Data, view: &mut Self::View, context: ViewContext<C>, frame: &mut G)
383 where
384 G: Frame,
385 C: ColModify,
386 {
387 match self.0 {
388 AndThenPrivate::First { ref t, .. } => t.view(data, view, context, frame),
389 AndThenPrivate::Second(ref u) => u.view(data, view, context, frame),
390 }
391 }
392}
393
394pub trait DataSelector {
395 type DataInput;
396 type DataOutput;
397 fn data<'a>(&self, input: &'a Self::DataInput) -> &'a Self::DataOutput;
398 fn data_mut<'a>(&self, input: &'a mut Self::DataInput) -> &'a mut Self::DataOutput;
399}
400
401pub trait ViewSelector {
402 type ViewInput;
403 type ViewOutput;
404 fn view<'a>(&self, input: &'a Self::ViewInput) -> &'a Self::ViewOutput;
405 fn view_mut<'a>(&self, input: &'a mut Self::ViewInput) -> &'a mut Self::ViewOutput;
406}
407
408pub trait Selector: DataSelector + ViewSelector {}
409
410#[derive(Clone, Copy)]
411pub struct Select<T, S> {
412 t: T,
413 selector: S,
414}
415
416impl<T, S> EventRoutine for Select<T, S>
417where
418 T: EventRoutine,
419 S: Selector<DataOutput = T::Data, ViewOutput = T::View>,
420{
421 type Return = T::Return;
422 type Data = S::DataInput;
423 type View = S::ViewInput;
424 type Event = T::Event;
425
426 fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, event_or_peek: EP) -> Handled<Self::Return, Self>
427 where
428 EP: EventOrPeek<Event = Self::Event>,
429 {
430 let Self { t, selector } = self;
431 t.handle(selector.data_mut(data), selector.view(view), event_or_peek)
432 .map_continue(|t| Self { t, selector })
433 }
434
435 fn view<F, C>(&self, data: &Self::Data, view: &mut Self::View, context: ViewContext<C>, frame: &mut F)
436 where
437 F: Frame,
438 C: ColModify,
439 {
440 self.t
441 .view(self.selector.data(data), self.selector.view_mut(view), context, frame)
442 }
443}
444
445pub struct Repeat<T, F> {
446 t: T,
447 f: F,
448}
449impl<T, U, F> EventRoutine for Repeat<T, F>
450where
451 T: EventRoutine,
452 F: FnMut(T::Return) -> Handled<U, T>,
453{
454 type Return = U;
455 type Data = T::Data;
456 type View = T::View;
457 type Event = T::Event;
458
459 fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, event_or_peek: EP) -> Handled<Self::Return, Self>
460 where
461 EP: EventOrPeek<Event = Self::Event>,
462 {
463 let Self { t, mut f } = self;
464 match t.handle(data, view, event_or_peek) {
465 Handled::Continue(t) => Handled::Continue(Self { t, f }),
466 Handled::Return(r) => match f(r) {
467 Handled::Continue(t) => Handled::Continue(Self { t, f }),
468 Handled::Return(r) => Handled::Return(r),
469 },
470 }
471 }
472
473 fn view<G, C>(&self, data: &Self::Data, view: &mut Self::View, context: ViewContext<C>, frame: &mut G)
474 where
475 G: Frame,
476 C: ColModify,
477 {
478 self.t.view(data, view, context, frame)
479 }
480}
481
482pub struct EventRoutineView<'e, 'v, E: EventRoutine> {
483 pub event_routine: &'e E,
484 pub view: &'v mut E::View,
485}
486
487impl<'e, 'v, 'd, E> View<&'d E::Data> for EventRoutineView<'e, 'v, E>
488where
489 E: EventRoutine,
490{
491 fn view<F: Frame, C: ColModify>(&mut self, data: &'d E::Data, context: ViewContext<C>, frame: &mut F) {
492 self.event_routine.view(data, self.view, context, frame)
493 }
494}
495
496pub trait Decorate {
497 type View;
498 type Data;
499
500 fn view<E, F, C>(
501 data: &Self::Data,
502 event_routine_view: EventRoutineView<E>,
503 context: ViewContext<C>,
504 frame: &mut F,
505 ) where
506 E: EventRoutine<Data = Self::Data, View = Self::View>,
507 F: Frame,
508 C: ColModify;
509}
510
511pub struct Decorated<T, D> {
512 t: T,
513 d: D,
514}
515
516impl<T, D> EventRoutine for Decorated<T, D>
517where
518 T: EventRoutine,
519 D: Decorate<View = T::View, Data = T::Data>,
520{
521 type Return = T::Return;
522 type Data = T::Data;
523 type View = T::View;
524 type Event = T::Event;
525
526 fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, event_or_peek: EP) -> Handled<Self::Return, Self>
527 where
528 EP: EventOrPeek<Event = Self::Event>,
529 {
530 let Self { t, d } = self;
531 t.handle(data, view, event_or_peek).map_continue(|t| Self { t, d })
532 }
533
534 fn view<F, C>(&self, data: &Self::Data, view: &mut Self::View, context: ViewContext<C>, frame: &mut F)
535 where
536 F: Frame,
537 C: ColModify,
538 {
539 let event_routine_view = EventRoutineView {
540 event_routine: &self.t,
541 view,
542 };
543 D::view(data, event_routine_view, context, frame)
544 }
545}
546
547pub struct OnEvent<T, F> {
548 t: T,
549 f: F,
550}
551
552impl<T, F> EventRoutine for OnEvent<T, F>
553where
554 T: EventRoutine,
555 F: FnMut(&mut &mut T::Data, &T::Event),
556{
557 type Return = T::Return;
558 type Data = T::Data;
559 type View = T::View;
560 type Event = T::Event;
561
562 fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, event_or_peek: EP) -> Handled<Self::Return, Self>
563 where
564 EP: EventOrPeek<Event = Self::Event>,
565 {
566 let on_peek = |(s, data)| {
567 let Self { t, f } = s;
568 t.handle(data, view, Peek::new()).map_continue(|t| Self { t, f })
569 };
570 let on_event = |(s, mut data), event| {
571 let Self { t, mut f } = s;
572 (f)(&mut data, &event);
573 t.handle(data, view, Event::new(event)).map_continue(|t| Self { t, f })
574 };
575 event_or_peek.with((self, data), on_event, on_peek)
576 }
577
578 fn view<G, C>(&self, data: &Self::Data, view: &mut Self::View, context: ViewContext<C>, frame: &mut G)
579 where
580 G: Frame,
581 C: ColModify,
582 {
583 self.t.view(data, view, context, frame);
584 }
585}
586
587make_either!(Either = Left | Right);
588
589#[macro_export]
590macro_rules! make_either {
591 ($type:ident = $first:ident | $($rest:ident)|*) => {
592 pub enum $type<$first, $($rest),*> {
593 $first($first),
594 $($rest($rest)),*
595 }
596 impl<$first, $($rest),*> EventRoutine for $type<$first, $($rest),*>
597 where
598 $first: EventRoutine,
599 $($rest: EventRoutine<Data = $first::Data, View = $first::View, Return = $first::Return, Event = $first::Event>),*
600 {
601 type Return = $first::Return;
602 type Data = $first::Data;
603 type View = $first::View;
604 type Event = $first::Event;
605
606 fn handle<EP>(self, data: &mut Self::Data, view: &Self::View, event_or_peek: EP) -> Handled<Self::Return, Self>
607 where
608 EP: EventOrPeek<Event = Self::Event>,
609 {
610 match self {
611 $type::$first(x) => x.handle(data, view, event_or_peek).map_continue($type::$first),
612 $($type::$rest(x) => x.handle(data, view, event_or_peek).map_continue($type::$rest)),*
613 }
614 }
615 fn view<FR, CM>(&self, data: &Self::Data, view: &mut Self::View, context: ViewContext<CM>, frame: &mut FR)
616 where
617 FR: Frame,
618 CM: ColModify,
619 {
620 match self {
621 $type::$first(x) => x.view(data, view, context, frame),
622 $($type::$rest(x) => x.view(data, view, context, frame)),*
623 }
624 }
625 }
626 };
627}