1use std::ops::{Deref, DerefMut};
2
3use crate::loc::Layer;
4use crate::log::{SpanLogger, Trackable};
5use crate::wave::exchange::asynch::Exchanger;
6use crate::wave::{DirectedWave, Ping, Pong, ReflectedWave, SingularDirectedWave, UltraWave, Wave};
7use crate::{ParticleRecord, SpaceErr, Surface};
8use crate::point::Point;
9
10#[async_trait]
11pub trait TraversalLayer {
12 fn surface(&self) -> Surface;
13
14 async fn traverse_next(&self, traversal: Traversal<UltraWave>);
15 async fn inject(&self, wave: UltraWave);
16
17 fn exchanger(&self) -> &Exchanger;
18
19 async fn deliver_directed(&self, direct: Traversal<DirectedWave>) -> Result<(), SpaceErr> {
20 Err(SpaceErr::server_error(
21 "this layer does not handle directed messages",
22 ))
23 }
24
25 async fn deliver_reflected(&self, reflect: Traversal<ReflectedWave>) -> Result<(), SpaceErr> {
26 self.exchanger().reflected(reflect.payload).await
27 }
28
29 async fn visit(&self, traversal: Traversal<UltraWave>) -> Result<(), SpaceErr> {
30 if let Some(dest) = &traversal.dest {
31 if self.surface().layer == *dest {
32 if traversal.is_directed() {
33 self.deliver_directed(traversal.unwrap_directed()).await?;
34 } else {
35 self.deliver_reflected(traversal.unwrap_reflected()).await?;
36 }
37 return Ok(());
38 } else {
39 }
40 }
41
42 if traversal.is_directed() && traversal.dir == TraversalDirection::Fabric {
43 self.directed_fabric_bound(traversal.unwrap_directed())
44 .await?;
45 } else if traversal.is_reflected() && traversal.dir == TraversalDirection::Core {
46 self.reflected_core_bound(traversal.unwrap_reflected())
47 .await?;
48 } else if traversal.is_directed() && traversal.dir == TraversalDirection::Core {
49 self.directed_core_bound(traversal.unwrap_directed())
50 .await?;
51 } else if traversal.is_reflected() && traversal.dir == TraversalDirection::Fabric {
52 self.reflected_fabric_bound(traversal.unwrap_reflected())
53 .await?;
54 }
55
56 Ok(())
57 }
58
59 async fn directed_fabric_bound(
61 &self,
62 mut traversal: Traversal<DirectedWave>,
63 ) -> Result<(), SpaceErr> {
64 self.traverse_next(traversal.wrap()).await;
65 Ok(())
66 }
67
68 async fn directed_core_bound(
69 &self,
70 mut traversal: Traversal<DirectedWave>,
71 ) -> Result<(), SpaceErr> {
72 self.traverse_next(traversal.wrap()).await;
73 Ok(())
74 }
75
76 async fn reflected_core_bound(
78 &self,
79 traversal: Traversal<ReflectedWave>,
80 ) -> Result<(), SpaceErr> {
81 self.traverse_next(traversal.to_ultra()).await;
82 Ok(())
83 }
84
85 async fn reflected_fabric_bound(
86 &self,
87 traversal: Traversal<ReflectedWave>,
88 ) -> Result<(), SpaceErr> {
89 self.traverse_next(traversal.to_ultra()).await;
90 Ok(())
91 }
92}
93
94#[derive(Clone)]
95pub struct TraversalPlan {
96 pub stack: Vec<Layer>,
97}
98
99impl TraversalPlan {
100 pub fn new(stack: Vec<Layer>) -> Self {
101 Self { stack }
102 }
103
104 pub fn towards_fabric(&self, layer: &Layer) -> Option<Layer> {
105 let mut layer = layer.clone();
106 let mut index: i32 = layer.ordinal() as i32;
107 loop {
108 index = index - 1;
109
110 if index < 0i32 {
111 return None;
112 } else if self
113 .stack
114 .contains(&Layer::from_ordinal(index as u8).unwrap())
115 {
116 return Some(Layer::from_ordinal(index as u8).unwrap());
117 }
118 }
119 }
120
121 pub fn towards_core(&self, layer: &Layer) -> Option<Layer> {
122 let mut layer = layer.clone();
123 let mut index = layer.ordinal();
124 loop {
125 index = index + 1;
126 let layer = match Layer::from_ordinal(index) {
127 Some(layer) => layer,
128 None => {
129 return None;
130 }
131 };
132
133 if self.stack.contains(&layer) {
134 return Some(layer);
135 }
136 }
137 }
138
139 pub fn has_layer(&self, layer: &Layer) -> bool {
140 self.stack.contains(layer)
141 }
142}
143
144#[derive(Clone)]
145pub struct TraversalInjection {
146 pub surface: Surface,
147 pub wave: UltraWave,
148 pub from_gravity: bool,
149 pub dir: Option<TraversalDirection>,
150}
151
152impl TraversalInjection {
153 pub fn new(injector: Surface, wave: UltraWave) -> Self {
154 Self {
155 surface: injector,
156 wave,
157 from_gravity: false,
158 dir: None,
159 }
160 }
161}
162
163#[derive(Clone)]
164pub struct Traversal<W> {
165 pub point: Point,
166 pub payload: W,
167 pub record: ParticleRecord,
168 pub layer: Layer,
169 pub dest: Option<Layer>,
170 pub logger: SpanLogger,
171 pub dir: TraversalDirection,
172 pub to: Surface,
173}
174
175impl<W> Trackable for Traversal<W>
176where
177 W: Trackable,
178{
179 fn track_id(&self) -> String {
180 self.payload.track_id()
181 }
182
183 fn track_method(&self) -> String {
184 self.payload.track_method()
185 }
186
187 fn track_payload(&self) -> String {
188 self.payload.track_payload()
189 }
190
191 fn track_from(&self) -> String {
192 self.payload.track_from()
193 }
194
195 fn track_to(&self) -> String {
196 self.payload.track_to()
197 }
198
199 fn track(&self) -> bool {
200 self.payload.track()
201 }
202}
203
204#[derive(Clone, Eq, PartialEq, Hash, strum_macros::Display)]
205pub enum TraversalDirection {
206 Fabric,
207 Core,
208}
209
210impl TraversalDirection {
211 pub fn new(from: &Layer, to: &Layer) -> Result<Self, SpaceErr> {
212 if from == to {
213 return Err(
214 "cannot determine traversal direction if from and to are the same layer".into(),
215 );
216 } else if from.ordinal() < to.ordinal() {
217 Ok(TraversalDirection::Core)
218 } else {
219 Ok(TraversalDirection::Fabric)
220 }
221 }
222
223 pub fn is_fabric(&self) -> bool {
224 match self {
225 TraversalDirection::Fabric => true,
226 TraversalDirection::Core => false,
227 }
228 }
229 pub fn is_core(&self) -> bool {
230 match self {
231 TraversalDirection::Fabric => false,
232 TraversalDirection::Core => true,
233 }
234 }
235}
236
237impl TraversalDirection {
238 pub fn reverse(&self) -> TraversalDirection {
239 match self {
240 Self::Fabric => Self::Core,
241 Self::Core => Self::Fabric,
242 }
243 }
244}
245
246impl<W> Traversal<W> {
247 pub fn new(
248 payload: W,
249 record: ParticleRecord,
250 layer: Layer,
251 logger: SpanLogger,
252 dir: TraversalDirection,
253 dest: Option<Layer>,
254 to: Surface,
255 point: Point,
256 ) -> Self {
257 Self {
258 payload,
259 record,
260 layer,
261 logger,
262 dir,
263 dest,
264 to,
265 point,
266 }
267 }
268
269 pub fn extract(self) -> W {
270 self.payload
271 }
272
273 pub fn with<N>(self, payload: N) -> Traversal<N> {
274 Traversal {
275 payload,
276 record: self.record,
277 layer: self.layer,
278 logger: self.logger,
279 dir: self.dir,
280 dest: self.dest,
281 to: self.to,
282 point: self.point,
283 }
284 }
285
286 pub fn reverse(&mut self) {
287 self.dir = self.dir.reverse();
288 }
289}
290
291impl<W> Traversal<W> {
292 pub fn next(&mut self) -> Option<Layer> {
293 let next = match self.dir {
294 TraversalDirection::Fabric => self
295 .record
296 .details
297 .stub
298 .kind
299 .wave_traversal_plan()
300 .towards_fabric(&self.layer),
301 TraversalDirection::Core => self
302 .record
303 .details
304 .stub
305 .kind
306 .wave_traversal_plan()
307 .towards_core(&self.layer),
308 };
309 match &next {
310 None => {}
311 Some(layer) => {
312 self.layer = layer.clone();
313 }
314 }
315 next
316 }
317
318 pub fn is_inter_layer(&self) -> bool {
319 self.to.point == *self.logger.point()
320 }
321}
322
323impl Traversal<UltraWave> {
324 pub fn is_fabric_bound(&self) -> bool {
325 match self.dir {
326 TraversalDirection::Fabric => true,
327 TraversalDirection::Core => false,
328 }
329 }
330
331 pub fn is_core_bound(&self) -> bool {
332 match self.dir {
333 TraversalDirection::Fabric => false,
334 TraversalDirection::Core => true,
335 }
336 }
337
338 pub fn is_ping(&self) -> bool {
339 match &self.payload {
340 UltraWave::Ping(_) => true,
341 _ => false,
342 }
343 }
344
345 pub fn is_pong(&self) -> bool {
346 match &self.payload {
347 UltraWave::Pong(_) => true,
348 _ => false,
349 }
350 }
351
352 pub fn is_directed(&self) -> bool {
353 match self.payload {
354 UltraWave::Ping(_) => true,
355 UltraWave::Pong(_) => false,
356 UltraWave::Ripple(_) => true,
357 UltraWave::Echo(_) => false,
358 UltraWave::Signal(_) => true,
359 }
360 }
361
362 pub fn is_reflected(&self) -> bool {
363 !self.is_directed()
364 }
365
366 pub fn unwrap_directed(self) -> Traversal<DirectedWave> {
367 let clone = self.clone();
368 match self.payload {
369 UltraWave::Ping(ping) => clone.with(ping.to_directed().clone()),
370 UltraWave::Ripple(ripple) => clone.with(ripple.to_directed()),
371 UltraWave::Signal(signal) => clone.with(signal.to_directed()),
372 _ => {
373 panic!("cannot call this unless you are sure it's a DirectedWave")
374 }
375 }
376 }
377
378 pub fn unwrap_singular_directed(self) -> Traversal<SingularDirectedWave> {
379 let clone = self.clone();
380 match self.payload {
381 UltraWave::Ping(ping) => clone.with(ping.to_singular_directed()),
382 UltraWave::Ripple(ripple) => {
383 clone.with(ripple.to_singular_directed().expect("singular directed"))
384 }
385 UltraWave::Signal(signal) => clone.with(signal.to_singular_directed()),
386 _ => {
387 panic!("cannot call this unless you are sure it's a DirectedWave")
388 }
389 }
390 }
391
392 pub fn unwrap_reflected(self) -> Traversal<ReflectedWave> {
393 let clone = self.clone();
394 match self.payload {
395 UltraWave::Pong(pong) => clone.with(pong.to_reflected()),
396 UltraWave::Echo(echo) => clone.with(echo.to_reflected()),
397 _ => {
398 panic!("cannot call this unless you are sure it's a ReflectedWave")
399 }
400 }
401 }
402
403 pub fn unwrap_ping(self) -> Traversal<Wave<Ping>> {
404 if let UltraWave::Ping(ping) = self.payload.clone() {
405 self.with(ping)
406 } else {
407 panic!("cannot call this unless you are sure it's a Ping")
408 }
409 }
410
411 pub fn unwrap_pong(self) -> Traversal<Wave<Pong>> {
412 if let UltraWave::Pong(pong) = self.payload.clone() {
413 self.with(pong)
414 } else {
415 panic!("cannot call this unless you are sure it's a Pong")
416 }
417 }
418}
419
420impl Traversal<DirectedWave> {
421 pub fn wrap(self) -> Traversal<UltraWave> {
422 let ping = self.payload.clone();
423 self.with(ping.to_ultra())
424 }
425}
426
427impl Traversal<ReflectedWave> {
428 pub fn wrap(self) -> Traversal<UltraWave> {
429 let ping = self.payload.clone();
430 self.with(ping.to_ultra())
431 }
432}
433
434impl Traversal<SingularDirectedWave> {
435 pub fn wrap(self) -> Traversal<UltraWave> {
436 let ping = self.payload.clone();
437 self.with(ping.to_ultra())
438 }
439}
440
441impl Traversal<ReflectedWave> {
442 pub fn to_ultra(self) -> Traversal<UltraWave> {
443 let pong = self.payload.clone();
444 self.with(pong.to_ultra())
445 }
446}
447
448impl Traversal<Wave<Ping>> {
449 pub fn to_ultra(self) -> Traversal<UltraWave> {
450 let ping = self.payload.clone();
451 self.with(ping.to_ultra())
452 }
453
454 pub fn to_directed(self) -> Traversal<DirectedWave> {
455 let ping = self.payload.clone();
456 self.with(ping.to_directed())
457 }
458}
459
460impl Traversal<Wave<Pong>> {
461 pub fn to_ultra(self) -> Traversal<UltraWave> {
462 let pong = self.payload.clone();
463 self.with(pong.to_ultra())
464 }
465
466 pub fn to_reflected(self) -> Traversal<ReflectedWave> {
467 let pong = self.payload.clone();
468 self.with(pong.to_reflected())
469 }
470}
471
472impl<W> Deref for Traversal<W> {
473 type Target = W;
474
475 fn deref(&self) -> &Self::Target {
476 &self.payload
477 }
478}
479
480impl<W> DerefMut for Traversal<W> {
481 fn deref_mut(&mut self) -> &mut Self::Target {
482 &mut self.payload
483 }
484}