1use counted_map::ReassignableCountedMap;
2
3use crate::{
4 exposed::Exposed,
5 receive::{Receive, ReceiverResult},
6 view::View,
7};
8
9pub trait Route<E>: Receive<E> {
10 fn intercept(&mut self, intercept: Box<dyn Route<E, Output = E>>);
11
12 fn take_intercept(&mut self) -> Option<Box<dyn Route<E, Output = E>>>;
13
14 fn intercept_at_root(&mut self, intercept: Box<dyn Route<E, Output = E>>) {
15 let old_intercept = self.take_intercept();
16 match old_intercept {
17 Some(r) => {
18 self.intercept(intercept);
19 self.intercept(r);
20 }
21 None => self.intercept(intercept),
22 }
23 }
24}
25
26pub struct Router<E, R: Receive<E>> {
27 intercept: Option<Box<dyn Route<E, Output = E>>>,
28 receiver: R,
29}
30
31impl<E, R: Receive<E>> Router<E, R> {
32 pub fn new(receiver: R) -> Self {
33 Self {
34 intercept: None,
35 receiver,
36 }
37 }
38
39 pub fn with_intercept(intercept: Box<dyn Route<E, Output = E>>, receiver: R) -> Self {
40 Self {
41 intercept: Some(intercept),
42 receiver,
43 }
44 }
45
46 pub fn with_intercept_from_receiver(
47 intercept: impl Receive<E, Output = E> + 'static,
48 receiver: R,
49 ) -> Self
50 where
51 E: 'static,
52 {
53 Self::with_intercept(Box::new(Router::new(intercept)), receiver)
54 }
55
56 pub fn new_exposed(receiver: R) -> Router<E, Exposed<E, R>> {
57 Router {
58 intercept: None,
59 receiver: Exposed::new(receiver),
60 }
61 }
62
63 pub fn new_exposed_with_viewers(
64 receiver: R,
65 viewers: ReassignableCountedMap<usize, Box<dyn View<E>>>,
66 ) -> Router<E, Exposed<E, R>> {
67 Router {
68 intercept: None,
69 receiver: Exposed::with_viewers(viewers, receiver),
70 }
71 }
72
73 pub fn new_exposed_with_intercept(
74 intercept: Box<dyn Route<E, Output = E>>,
75 receiver: R,
76 ) -> Router<E, Exposed<E, R>> {
77 Router {
78 intercept: Some(intercept),
79 receiver: Exposed::new(receiver),
80 }
81 }
82
83 pub fn new_exposed_with_intercept_from_receiver(
84 intercept: impl Receive<E, Output = E> + 'static,
85 receiver: R,
86 ) -> Router<E, Exposed<E, R>>
87 where
88 E: 'static,
89 {
90 Router::new_exposed_with_intercept(Box::new(Router::new(intercept)), receiver)
91 }
92
93 pub fn get_receiver(&self) -> &R {
94 &self.receiver
95 }
96
97 pub fn get_receiver_mut(&mut self) -> &mut R {
98 &mut self.receiver
99 }
100
101 pub fn get_intercept(&self) -> Option<&dyn Route<E, Output = E>> {
102 self.intercept.as_ref().map(Box::as_ref)
103 }
104
105 pub fn intercept_from_receiver(&mut self, intercept: impl Receive<E, Output = E> + 'static)
106 where
107 E: 'static,
108 {
109 let intercept = Box::new(Router::new(intercept));
110 self.intercept(intercept);
111 }
112
113 pub fn intercept_at_root_from_receiver(
114 &mut self,
115 intercept: impl Receive<E, Output = E> + 'static,
116 ) where
117 E: 'static,
118 {
119 let intercept = Box::new(Router::new(intercept));
120 self.intercept_at_root(intercept);
121 }
122
123 pub fn delete_top_intercept(&mut self) -> Option<Box<dyn Route<E, Output = E>>> {
124 let mut old_intercept = self.take_intercept();
125 if let Some(ref mut intercept) = old_intercept {
126 self.intercept = intercept.take_intercept();
127 }
128 old_intercept
129 }
130}
131
132impl<E, R: Receive<E>> Receive<E> for Router<E, R> {
133 type Output = R::Output;
134 fn send(&mut self, event: E) -> ReceiverResult<E, Self::Output> {
135 let event = if let Some(ref mut intercept) = self.intercept {
136 match intercept.send(event) {
137 ReceiverResult::Continue(event) => event,
138 ReceiverResult::Stop => return ReceiverResult::Stop,
139 ReceiverResult::Delete(event) => {
140 self.delete_top_intercept().unwrap();
141 event
142 }
143 }
144 } else {
145 event
146 };
147
148 self.receiver.send(event)
149 }
150}
151
152impl<E, R: Receive<E>> Route<E> for Router<E, R> {
153 fn intercept(&mut self, intercept: Box<dyn Route<E, Output = E>>) {
154 match self.intercept {
155 Some(ref mut child) => child.intercept(intercept),
156 None => self.intercept = Some(intercept),
157 }
158 }
159
160 fn take_intercept(&mut self) -> Option<Box<dyn Route<E, Output = E>>> {
161 self.intercept.take()
162 }
163}
164
165impl<E, R: Receive<E> + Default> Default for Router<E, R> {
166 fn default() -> Self {
167 Self::new(R::default())
168 }
169}
170
171impl<E, R: Receive<E> + std::fmt::Debug> std::fmt::Debug for Router<E, R> {
172 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
173 write!(f, "{{")?;
174 match self.intercept {
175 Some(_) => write!(f, "intercepted, ")?,
176 None => write!(f, "no intercept, ")?,
177 }
178 write!(f, "receiver: {:?}}}", self.receiver)
179 }
180}
181
182impl<E, R: Receive<E> + std::fmt::Display> std::fmt::Display for Router<E, R> {
183 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
184 self.receiver.fmt(f)
185 }
186}