cosmic_space/
wave.rs

1use ::core::borrow::Borrow;
2use alloc::borrow::Cow;
3use std::collections::{HashMap, HashSet};
4use std::convert::Infallible;
5use std::env::var;
6use std::marker::PhantomData;
7use std::ops;
8use std::ops::{Deref, DerefMut};
9use std::sync::Arc;
10use std::time::Duration;
11
12use dashmap::DashMap;
13use serde::{Deserialize, Serialize};
14use tokio::sync::{broadcast, mpsc, oneshot, RwLock};
15use tokio::time::Instant;
16
17use cosmic_macros_primitive::Autobox;
18use cosmic_nom::{Res, SpanExtra};
19use exchange::asynch::ProtoTransmitter;
20
21use crate::command::Command;
22use crate::command::RawCommand;
23use crate::config::bind::RouteSelector;
24use crate::err::{CoreReflector, SpaceErr, StatusErr};
25use crate::hyper::AssignmentKind;
26use crate::hyper::InterchangeKind::DefaultControl;
27use crate::kind::Sub;
28use crate::loc::StarKey;
29use crate::loc::{
30    Layer, Surface, SurfaceSelector, Topic, ToPoint, ToSurface, Uuid,
31};
32use crate::log::{
33    LogSpan, LogSpanEvent, PointLogger, RootLogger, SpanLogger, Spannable, Trackable, TrailSpanId,
34};
35use crate::parse::model::Subst;
36use crate::parse::sub;
37use crate::particle::Watch;
38use crate::particle::{Details, Status};
39use crate::security::{Permissions, Privilege, Privileges};
40use crate::selector::Selector;
41use crate::settings::Timeouts;
42use crate::substance::Bin;
43use crate::substance::{
44    Call, CallKind, CmdCall, ExtCall, FormErrs, HttpCall, HypCall, MultipartFormBuilder, Substance,
45    SubstanceKind, Token, ToRequestCore, ToSubstance,
46};
47use crate::util::{uuid, ValueMatcher, ValuePattern};
48use crate::wave::core::http2::StatusCode;
49use crate::{ANONYMOUS, HYPERUSER};
50use url::Url;
51use crate::point::{Point, PointSeg, RouteSeg};
52
53use self::core::cmd::CmdMethod;
54use self::core::ext::ExtMethod;
55use self::core::http2::HttpMethod;
56use self::core::hyp::HypMethod;
57use self::core::{CoreBounce, DirectedCore, Method, ReflectedCore};
58
59pub mod core;
60pub mod exchange;
61
62#[derive(
63    Debug,
64    Clone,
65    Serialize,
66    Deserialize,
67    Eq,
68    PartialEq,
69    Hash,
70    strum_macros::Display,
71    strum_macros::EnumString,
72)]
73pub enum WaveKind {
74    Ping,   // Request
75    Pong,   // Response
76    Ripple, // Broadcast
77    Echo,   // Broadcast Response
78    Signal, // Notification
79            /*
80            Photon, // Ack
81                   Reverb,  // Ack
82                  */
83}
84
85impl WaveKind {
86    pub fn reflected_kind(&self) -> Result<ReflectedKind, SpaceErr> {
87        match self {
88            WaveKind::Pong => Ok(ReflectedKind::Pong),
89            WaveKind::Echo => Ok(ReflectedKind::Echo),
90            _ => Err(SpaceErr::bad_request("expected a reflected WaveKind")),
91        }
92    }
93}
94
95pub type UltraWave = UltraWaveDef<Recipients>;
96pub type SingularUltraWave = UltraWaveDef<Surface>;
97
98impl SingularUltraWave {
99    pub fn to_ultra(self) -> Result<UltraWave, SpaceErr> {
100        match self {
101            SingularUltraWave::Ping(ping) => Ok(UltraWave::Ping(ping)),
102            SingularUltraWave::Pong(pong) => Ok(UltraWave::Pong(pong)),
103            SingularUltraWave::Echo(echo) => Ok(UltraWave::Echo(echo)),
104            SingularUltraWave::Signal(signal) => Ok(UltraWave::Signal(signal)),
105            SingularUltraWave::Ripple(ripple) => {
106                let ripple = ripple.to_multiple();
107                Ok(UltraWave::Ripple(ripple))
108            }
109        }
110    }
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
114pub enum UltraWaveDef<T>
115where
116    T: ToRecipients + Clone,
117{
118    Ping(Wave<Ping>),
119    Pong(Wave<Pong>),
120    Ripple(Wave<RippleDef<T>>),
121    Echo(Wave<Echo>),
122    Signal(Wave<Signal>),
123}
124
125impl<W> Spannable for UltraWaveDef<W>
126where
127    W: ToRecipients + Clone,
128{
129    fn span_id(&self) -> String {
130        self.id().to_string()
131    }
132
133    fn span_type(&self) -> &'static str {
134        "Wave"
135    }
136}
137
138impl Trackable for UltraWave {
139    fn track_id(&self) -> String {
140        self.id().to_short_string()
141    }
142
143    fn track_method(&self) -> String {
144        match self {
145            UltraWave::Ping(ping) => ping.core.method.to_deep_string(),
146            UltraWave::Pong(pong) => pong.core.status.to_string(),
147            UltraWave::Ripple(ripple) => ripple.core.method.to_deep_string(),
148            UltraWave::Echo(echo) => echo.core.status.to_string(),
149            UltraWave::Signal(signal) => signal.core.method.to_deep_string(),
150        }
151    }
152
153    fn track_payload(&self) -> String {
154        match self {
155            UltraWave::Ping(ping) => ping.core.body.kind().to_string(),
156            UltraWave::Pong(pong) => pong.core.body.kind().to_string(),
157            UltraWave::Ripple(ripple) => ripple.core.body.kind().to_string(),
158            UltraWave::Echo(echo) => echo.core.body.kind().to_string(),
159            UltraWave::Signal(signal) => signal.core.body.kind().to_string(),
160        }
161    }
162
163    fn track_from(&self) -> String {
164        self.from().to_string()
165    }
166
167    fn track_to(&self) -> String {
168        self.to().to_string()
169    }
170
171    fn track(&self) -> bool {
172        match self {
173            UltraWave::Ping(ping) => ping.track,
174            UltraWave::Pong(pong) => pong.track,
175            UltraWave::Ripple(ripple) => ripple.track,
176            UltraWave::Echo(echo) => echo.track,
177            UltraWave::Signal(signal) => signal.track,
178        }
179    }
180    fn track_payload_fmt(&self) -> String {
181        match self {
182            UltraWave::Signal(signal) => signal.track_payload_fmt(),
183            UltraWave::Ping(_) => self.track_payload(),
184            UltraWave::Pong(_) => self.track_payload(),
185            UltraWave::Ripple(_) => self.track_payload(),
186            UltraWave::Echo(_) => self.track_payload(),
187        }
188    }
189}
190
191impl<T> UltraWaveDef<T>
192where
193    T: ToRecipients + Clone,
194{
195    pub fn via_desc(&self) -> String {
196        let via = match self {
197            UltraWaveDef::Ping(w) => w.via.as_ref(),
198            UltraWaveDef::Pong(w) => w.via.as_ref(),
199            UltraWaveDef::Ripple(w) => w.via.as_ref(),
200            UltraWaveDef::Echo(w) => w.via.as_ref(),
201            UltraWaveDef::Signal(w) => w.via.as_ref(),
202        };
203
204        match via {
205            None => "None".to_string(),
206            Some(via) => via.to_string(),
207        }
208    }
209
210    pub fn has_visited(&self, star: &Point) -> bool {
211        match self {
212            UltraWaveDef::Ripple(ripple) => ripple.history.contains(star),
213            _ => false,
214        }
215    }
216
217    pub fn add_history(&mut self, point: &Point) {
218        match self {
219            UltraWaveDef::Ping(_) => {}
220            UltraWaveDef::Pong(_) => {}
221            UltraWaveDef::Ripple(ripple) => {
222                ripple.history.insert(point.clone());
223            }
224            UltraWaveDef::Echo(_) => {}
225            UltraWaveDef::Signal(_) => {}
226        }
227    }
228
229    pub fn history(&self) -> HashSet<Point> {
230        match self {
231            UltraWaveDef::Ping(_) => HashSet::new(),
232            UltraWaveDef::Pong(_) => HashSet::new(),
233            UltraWaveDef::Ripple(ripple) => ripple.history.clone(),
234            UltraWaveDef::Echo(_) => HashSet::new(),
235            UltraWaveDef::Signal(_) => HashSet::new(),
236        }
237    }
238
239    pub fn id(&self) -> WaveId {
240        match self {
241            UltraWaveDef::Ping(w) => w.id.clone(),
242            UltraWaveDef::Pong(w) => w.id.clone(),
243            UltraWaveDef::Ripple(w) => w.id.clone(),
244            UltraWaveDef::Echo(w) => w.id.clone(),
245            UltraWaveDef::Signal(w) => w.id.clone(),
246        }
247    }
248
249    pub fn body(&self) -> &Substance {
250        match self {
251            UltraWaveDef::Ping(ping) => &ping.body,
252            UltraWaveDef::Pong(pong) => &pong.core.body,
253            UltraWaveDef::Ripple(ripple) => &ripple.body,
254            UltraWaveDef::Echo(echo) => &echo.core.body,
255            UltraWaveDef::Signal(signal) => &signal.core.body,
256        }
257    }
258
259    pub fn payload(&self) -> Option<&UltraWave> {
260        if let Substance::UltraWave(wave) = self.body() {
261            Some(wave)
262        } else {
263            None
264        }
265    }
266}
267
268impl UltraWave {
269    pub fn can_shard(&self) -> bool {
270        match self {
271            UltraWave::Ripple(_) => true,
272            _ => false,
273        }
274    }
275
276    pub fn to_singular(self) -> Result<SingularUltraWave, SpaceErr> {
277        match self {
278            UltraWave::Ping(ping) => Ok(SingularUltraWave::Ping(ping)),
279            UltraWave::Pong(pong) => Ok(SingularUltraWave::Pong(pong)),
280            UltraWave::Echo(echo) => Ok(SingularUltraWave::Echo(echo)),
281            UltraWave::Signal(signal) => Ok(SingularUltraWave::Signal(signal)),
282            UltraWave::Ripple(_) => Err(SpaceErr::server_error(
283                "cannot change Ripple into a singular",
284            )),
285        }
286    }
287
288    pub fn wrap_in_transport(self, from: Surface, to: Surface) -> DirectedProto {
289        let mut signal = DirectedProto::signal();
290        signal.fill(&self);
291        signal.from(from);
292        signal.agent(self.agent().clone());
293        signal.handling(self.handling().clone());
294        signal.method(HypMethod::Transport);
295        //        signal.track = self.track();
296        signal.body(Substance::UltraWave(Box::new(self)));
297        signal.to(to);
298        signal
299    }
300
301    pub fn unwrap_from_hop(self) -> Result<Wave<Signal>, SpaceErr> {
302        let signal = self.to_signal()?;
303        signal.unwrap_from_hop()
304    }
305
306    pub fn unwrap_from_transport(self) -> Result<UltraWave, SpaceErr> {
307        let signal = self.to_signal()?;
308        signal.unwrap_from_transport()
309    }
310
311    pub fn to_substance(self) -> Substance {
312        Substance::UltraWave(Box::new(self))
313    }
314
315    pub fn to_directed(self) -> Result<DirectedWave, SpaceErr> {
316        match self {
317            UltraWave::Ping(ping) => Ok(ping.to_directed()),
318            UltraWave::Ripple(ripple) => Ok(ripple.to_directed()),
319            UltraWave::Signal(signal) => Ok(signal.to_directed()),
320            _ => Err(SpaceErr::bad_request("expected a DirectedWave")),
321        }
322    }
323
324    pub fn to_reflected(self) -> Result<ReflectedWave, SpaceErr> {
325        match self {
326            UltraWave::Pong(pong) => Ok(pong.to_reflected()),
327            UltraWave::Echo(echo) => Ok(echo.to_reflected()),
328            _ => Err(SpaceErr::bad_request(format!(
329                "expected: ReflectedWave; encountered: {}",
330                self.desc()
331            ))),
332        }
333    }
334
335    pub fn kind(&self) -> WaveKind {
336        match self {
337            UltraWave::Ping(_) => WaveKind::Ping,
338            UltraWave::Pong(_) => WaveKind::Pong,
339            UltraWave::Ripple(_) => WaveKind::Ripple,
340            UltraWave::Echo(_) => WaveKind::Echo,
341            UltraWave::Signal(_) => WaveKind::Signal,
342        }
343    }
344
345    /// return a description of this wave for debugging purposes
346    pub fn desc(&self) -> String {
347        if self.is_directed() {
348            let directed = self.clone().to_directed().unwrap();
349            format!(
350                "{}<{}>[{}]",
351                self.kind().to_string(),
352                directed.core().method.to_string(),
353                directed.core().body.kind().to_string()
354            )
355        } else {
356            let reflected = self.clone().to_reflected().unwrap();
357            format!(
358                "{}<{}>[{}]",
359                self.kind().to_string(),
360                reflected.core().status.to_string(),
361                reflected.core().body.kind().to_string()
362            )
363        }
364    }
365
366    pub fn hops(&self) -> u16 {
367        match self {
368            UltraWave::Ping(w) => w.hops,
369            UltraWave::Pong(w) => w.hops,
370            UltraWave::Ripple(w) => w.hops,
371            UltraWave::Echo(w) => w.hops,
372            UltraWave::Signal(w) => w.hops,
373        }
374    }
375
376    pub fn max_hops(&self) -> u16 {
377        if let Some(wave) = self.transported() {
378            let child = wave.max_hops();
379            if child > self.hops() {
380                return child;
381            }
382        }
383        self.hops()
384    }
385
386    pub fn inc_hops(&mut self) {
387        match self {
388            UltraWave::Ping(w) => w.hops += 1,
389            UltraWave::Pong(w) => w.hops += 1,
390            UltraWave::Ripple(w) => w.hops += 1,
391            UltraWave::Echo(w) => w.hops += 1,
392            UltraWave::Signal(w) => w.hops += 1,
393        };
394
395        if let Some(wave) = self.transported_mut() {
396            wave.inc_hops();
397        }
398    }
399
400    pub fn add_to_history(&mut self, star: Point) {
401        match self {
402            UltraWave::Ripple(ripple) => {
403                ripple.history.insert(star);
404            }
405            _ => {}
406        }
407    }
408
409    pub fn to_signal(self) -> Result<Wave<Signal>, SpaceErr> {
410        match self {
411            UltraWave::Signal(signal) => Ok(signal),
412            _ => Err(SpaceErr::bad_request(format!(
413                "expecting: Wave<Signal> encountered: Wave<{}>",
414                self.kind().to_string()
415            ))),
416        }
417    }
418
419    pub fn method(&self) -> Option<&Method> {
420        match self {
421            UltraWave::Ping(ping) => Some(&ping.method),
422            UltraWave::Ripple(ripple) => Some(&ripple.method),
423            UltraWave::Signal(signal) => Some(&signal.method),
424            _ => None,
425        }
426    }
427
428    pub fn is_directed(&self) -> bool {
429        match self {
430            UltraWave::Ping(_) => true,
431            UltraWave::Pong(_) => false,
432            UltraWave::Ripple(_) => true,
433            UltraWave::Echo(_) => false,
434            UltraWave::Signal(_) => true,
435        }
436    }
437
438    pub fn is_reflected(&self) -> bool {
439        match self {
440            UltraWave::Ping(_) => false,
441            UltraWave::Pong(_) => true,
442            UltraWave::Ripple(_) => false,
443            UltraWave::Echo(_) => true,
444            UltraWave::Signal(_) => false,
445        }
446    }
447
448    pub fn to(&self) -> Recipients {
449        match self {
450            UltraWave::Ping(ping) => ping.to.clone().to_recipients(),
451            UltraWave::Pong(pong) => pong.to.clone().to_recipients(),
452            UltraWave::Ripple(ripple) => ripple.to.clone(),
453            UltraWave::Echo(echo) => echo.to.clone().to_recipients(),
454            UltraWave::Signal(signal) => signal.to.clone().to_recipients(),
455        }
456    }
457
458    pub fn from(&self) -> &Surface {
459        match self {
460            UltraWave::Ping(ping) => &ping.from,
461            UltraWave::Pong(pong) => &pong.from,
462            UltraWave::Ripple(ripple) => &ripple.from,
463            UltraWave::Echo(echo) => &echo.from,
464            UltraWave::Signal(signal) => &signal.from,
465        }
466    }
467
468    pub fn set_agent(&mut self, agent: Agent) {
469        match self {
470            UltraWave::Ping(ping) => ping.agent = agent,
471            UltraWave::Pong(pong) => pong.agent = agent,
472            UltraWave::Ripple(ripple) => ripple.agent = agent,
473            UltraWave::Echo(echo) => echo.agent = agent,
474            UltraWave::Signal(signal) => signal.agent = agent,
475        }
476    }
477
478    pub fn set_to(&mut self, to: Surface) {
479        match self {
480            UltraWave::Ping(ping) => ping.to = to,
481            UltraWave::Pong(pong) => pong.to = to,
482            UltraWave::Ripple(ripple) => ripple.to = to.to_recipients(),
483            UltraWave::Echo(echo) => echo.to = to,
484            UltraWave::Signal(signal) => signal.to = to,
485        }
486    }
487
488    pub fn set_from(&mut self, from: Surface) {
489        match self {
490            UltraWave::Ping(ping) => ping.from = from,
491            UltraWave::Pong(pong) => pong.from = from,
492            UltraWave::Ripple(ripple) => ripple.from = from,
493            UltraWave::Echo(echo) => echo.from = from,
494            UltraWave::Signal(signal) => signal.from = from,
495        }
496    }
497
498    pub fn agent(&self) -> &Agent {
499        match self {
500            UltraWave::Ping(ping) => &ping.agent,
501            UltraWave::Pong(pong) => &pong.agent,
502            UltraWave::Ripple(ripple) => &ripple.agent,
503            UltraWave::Echo(echo) => &echo.agent,
504            UltraWave::Signal(signal) => &signal.agent,
505        }
506    }
507
508    pub fn handling(&self) -> &Handling {
509        match self {
510            UltraWave::Ping(ping) => &ping.handling,
511            UltraWave::Pong(pong) => &pong.handling,
512            UltraWave::Ripple(ripple) => &ripple.handling,
513            UltraWave::Echo(echo) => &echo.handling,
514            UltraWave::Signal(signal) => &signal.handling,
515        }
516    }
517
518    pub fn track(&self) -> bool {
519        match self {
520            UltraWave::Ping(ping) => ping.track,
521            UltraWave::Pong(pong) => pong.track,
522            UltraWave::Ripple(ripple) => ripple.track,
523            UltraWave::Echo(echo) => echo.track,
524            UltraWave::Signal(signal) => signal.track,
525        }
526    }
527
528    pub fn set_track(&mut self, track: bool) {
529        match self {
530            UltraWave::Ping(ping) => ping.track = track,
531            UltraWave::Pong(pong) => pong.track = track,
532            UltraWave::Ripple(ripple) => ripple.track = track,
533            UltraWave::Echo(echo) => echo.track = track,
534            UltraWave::Signal(signal) => signal.track = track,
535        }
536    }
537
538    pub fn scope(&self) -> &Scope {
539        match self {
540            UltraWave::Ping(ping) => &ping.scope,
541            UltraWave::Pong(pong) => &pong.scope,
542            UltraWave::Ripple(ripple) => &ripple.scope,
543            UltraWave::Echo(echo) => &echo.scope,
544            UltraWave::Signal(signal) => &signal.scope,
545        }
546    }
547    pub fn to_ripple(self) -> Result<Wave<Ripple>, SpaceErr> {
548        match self {
549            UltraWave::Ripple(ripple) => Ok(ripple),
550            _ => Err("not a ripple".into()),
551        }
552    }
553
554    pub fn transported(&self) -> Option<&UltraWave> {
555        match self {
556            UltraWave::Ping(w) => w.core.body.ultrawave(),
557            UltraWave::Pong(w) => w.core.body.ultrawave(),
558            UltraWave::Ripple(w) => w.core.body.ultrawave(),
559            UltraWave::Echo(w) => w.core.body.ultrawave(),
560            UltraWave::Signal(w) => w.core.body.ultrawave(),
561        }
562    }
563
564    pub fn transported_mut(&mut self) -> Option<&mut UltraWave> {
565        match self {
566            UltraWave::Ping(w) => w.core.body.ultrawave_mut(),
567            UltraWave::Pong(w) => w.core.body.ultrawave_mut(),
568            UltraWave::Ripple(w) => w.core.body.ultrawave_mut(),
569            UltraWave::Echo(w) => w.core.body.ultrawave_mut(),
570            UltraWave::Signal(w) => w.core.body.ultrawave_mut(),
571        }
572    }
573}
574
575impl<S> ToSubstance<S> for UltraWave
576where
577    Substance: ToSubstance<S>,
578{
579    fn to_substance(self) -> Result<S, SpaceErr> {
580        match self {
581            UltraWave::Ping(ping) => ping.to_substance(),
582            UltraWave::Pong(pong) => pong.to_substance(),
583            UltraWave::Ripple(ripple) => ripple.to_substance(),
584            UltraWave::Echo(echo) => echo.to_substance(),
585            UltraWave::Signal(signal) => signal.to_substance(),
586        }
587    }
588
589    fn to_substance_ref(&self) -> Result<&S, SpaceErr> {
590        match self {
591            UltraWave::Ping(ping) => ping.to_substance_ref(),
592            UltraWave::Pong(pong) => pong.to_substance_ref(),
593            UltraWave::Ripple(ripple) => ripple.to_substance_ref(),
594            UltraWave::Echo(echo) => echo.to_substance_ref(),
595            UltraWave::Signal(signal) => signal.to_substance_ref(),
596        }
597    }
598}
599
600#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
601pub struct WaveId {
602    uuid: Uuid,
603    kind: WaveKind,
604}
605
606impl WaveId {
607    pub fn new(kind: WaveKind) -> Self {
608        let uuid = uuid();
609        Self::with_uuid(kind, uuid)
610    }
611
612    pub fn with_uuid(kind: WaveKind, uuid: Uuid) -> Self {
613        Self { uuid, kind }
614    }
615
616    pub fn to_short_string(&self) -> String {
617        if self.uuid.to_string().len() > 8 {
618            format!(
619                "<Wave<{}>>::{}",
620                self.kind.to_string(),
621                self.uuid.to_string().as_str()[..8].to_string()
622            )
623        } else {
624            self.to_string()
625        }
626    }
627}
628
629impl ToString for WaveId {
630    fn to_string(&self) -> String {
631        format!(
632            "<Wave<{}>>::{}",
633            self.kind.to_string(),
634            self.uuid.to_string()
635        )
636    }
637}
638
639pub trait Reflectable<R> {
640    fn forbidden(self, responder: Surface) -> R
641    where
642        Self: Sized,
643    {
644        self.status(403, responder)
645    }
646
647    fn bad_request(self, responder: Surface) -> R
648    where
649        Self: Sized,
650    {
651        self.status(400, responder)
652    }
653
654    fn not_found(self, responder: Surface) -> R
655    where
656        Self: Sized,
657    {
658        self.status(404, responder)
659    }
660
661    fn timeout(self, responder: Surface) -> R
662    where
663        Self: Sized,
664    {
665        self.status(408, responder)
666    }
667
668    fn server_error(self, responder: Surface) -> R
669    where
670        Self: Sized,
671    {
672        self.status(500, responder)
673    }
674
675    fn status(self, status: u16, responder: Surface) -> R
676    where
677        Self: Sized;
678
679    fn fail<M: ToString>(self, status: u16, message: M, responder: Surface) -> R
680    where
681        Self: Sized;
682
683    fn err(self, err: SpaceErr, responder: Surface) -> R
684    where
685        Self: Sized;
686
687    fn ok(self, responder: Surface) -> R
688    where
689        Self: Sized,
690    {
691        self.status(200, responder)
692    }
693
694    fn ok_body(self, body: Substance, responder: Surface) -> R
695    where
696        Self: Sized;
697
698    fn core(self, core: ReflectedCore, responder: Surface) -> R
699    where
700        Self: Sized;
701
702    fn result<C: Into<ReflectedCore>>(self, result: Result<C, SpaceErr>, responder: Surface) -> R
703    where
704        Self: Sized,
705    {
706        match result {
707            Ok(core) => self.core(core.into(), responder),
708            Err(err) => self.core(err.into(), responder),
709        }
710    }
711}
712
713#[derive(Debug, Clone, Serialize, Deserialize)]
714pub struct DirectWaveStub {
715    pub id: WaveId,
716    pub agent: Agent,
717    pub handling: Handling,
718    pub from: Surface,
719    pub to: Recipients,
720    pub span: Option<TrailSpanId>,
721}
722
723impl Into<WaitTime> for &DirectWaveStub {
724    fn into(self) -> WaitTime {
725        self.handling.wait.clone()
726    }
727}
728
729pub type Ripple = RippleDef<Recipients>;
730pub type SingularRipple = RippleDef<Surface>;
731
732#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
733pub struct RippleDef<T: ToRecipients + Clone> {
734    pub to: T,
735    pub core: DirectedCore,
736    pub bounce_backs: BounceBacks,
737    pub history: HashSet<Point>,
738}
739
740impl Ripple {
741    pub fn new<T>(core: DirectedCore, to: T, bounce_backs: BounceBacks) -> Self
742    where
743        T: ToRecipients,
744    {
745        Self {
746            to: to.to_recipients(),
747            core,
748            bounce_backs,
749            history: HashSet::new(),
750        }
751    }
752}
753
754impl<T> RippleDef<T>
755where
756    T: ToRecipients + Clone,
757{
758    pub fn replace_to<T2: ToRecipients + Clone>(self, to: T2) -> RippleDef<T2> {
759        RippleDef {
760            to,
761            core: self.core,
762            bounce_backs: self.bounce_backs,
763            history: self.history,
764        }
765    }
766}
767
768impl Wave<SingularRipple> {
769    pub fn to_singular_ultra(self) -> SingularUltraWave {
770        SingularUltraWave::Ripple(self)
771    }
772
773    pub fn to_multiple(self) -> Wave<Ripple> {
774        let ripple = self
775            .variant
776            .clone()
777            .replace_to(self.variant.to.clone().to_recipients());
778        self.replace(ripple)
779    }
780}
781
782impl Wave<SingularRipple> {
783    pub fn as_multi(&self, recipients: Recipients) -> Wave<Ripple> {
784        let ripple = self.variant.clone().replace_to(recipients);
785        self.clone().replace(ripple)
786    }
787}
788
789impl Wave<Ripple> {
790    pub fn as_single(&self, surface: Surface) -> Wave<SingularRipple> {
791        let ripple = self.variant.clone().replace_to(surface);
792        self.clone().replace(ripple)
793    }
794
795    pub fn to_singular_directed(self) -> Result<SingularDirectedWave, SpaceErr> {
796        let to = self.to.clone().to_single()?;
797        Ok(self.as_single(to).to_singular_directed())
798    }
799}
800
801#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
802pub enum BounceBacks {
803    None,
804    Single,
805    Count(usize),
806    Timer(WaitTime),
807}
808
809impl BounceBacks {
810    pub fn has_bounce(&self) -> bool {
811        match self {
812            BounceBacks::None => false,
813            BounceBacks::Single => true,
814            BounceBacks::Count(_) => true,
815            BounceBacks::Timer(_) => true,
816        }
817    }
818}
819
820impl<S, T> ToSubstance<S> for RippleDef<T>
821where
822    Substance: ToSubstance<S>,
823    T: ToRecipients + Clone,
824{
825    fn to_substance(self) -> Result<S, SpaceErr> {
826        self.core.to_substance()
827    }
828
829    fn to_substance_ref(&self) -> Result<&S, SpaceErr> {
830        self.core.to_substance_ref()
831    }
832}
833
834impl<T> RippleDef<T>
835where
836    T: ToRecipients + Clone,
837{
838    pub fn require_method<M: Into<Method> + ToString + Clone>(
839        self,
840        method: M,
841    ) -> Result<RippleDef<T>, SpaceErr> {
842        if self.core.method == method.clone().into() {
843            Ok(self)
844        } else {
845            Err(SpaceErr::new(
846                400,
847                format!("Bad Request: expecting method: {}", method.to_string()).as_str(),
848            ))
849        }
850    }
851
852    pub fn require_body<B>(self) -> Result<B, SpaceErr>
853    where
854        B: TryFrom<Substance, Error = SpaceErr>,
855    {
856        match B::try_from(self.body.clone()) {
857            Ok(body) => Ok(body),
858            Err(err) => Err(SpaceErr::bad_request("expected a body")),
859        }
860    }
861}
862
863impl<T> Deref for RippleDef<T>
864where
865    T: ToRecipients + Clone,
866{
867    type Target = DirectedCore;
868
869    fn deref(&self) -> &Self::Target {
870        &self.core
871    }
872}
873
874impl<T> DerefMut for RippleDef<T>
875where
876    T: ToRecipients + Clone,
877{
878    fn deref_mut(&mut self) -> &mut Self::Target {
879        &mut self.core
880    }
881}
882
883#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
884pub struct Signal {
885    pub to: Surface,
886    pub core: DirectedCore,
887}
888
889impl WaveVariant for Signal {
890    fn kind(&self) -> WaveKind {
891        WaveKind::Signal
892    }
893}
894
895impl Signal {
896    pub fn new(to: Surface, core: DirectedCore) -> Self {
897        Self { to, core }
898    }
899
900    pub fn bounce_backs(&self) -> BounceBacks {
901        BounceBacks::None
902    }
903}
904
905impl Deref for Signal {
906    type Target = DirectedCore;
907
908    fn deref(&self) -> &Self::Target {
909        &self.core
910    }
911}
912
913impl DerefMut for Signal {
914    fn deref_mut(&mut self) -> &mut Self::Target {
915        &mut self.core
916    }
917}
918
919#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
920pub struct Ping {
921    pub to: Surface,
922    pub core: DirectedCore,
923}
924
925impl Wave<Ping> {
926    pub fn to_singular_directed(self) -> SingularDirectedWave {
927        SingularDirectedWave::Ping(self)
928    }
929
930    pub fn with_core(mut self, core: DirectedCore) -> Self {
931        self.variant.core = core;
932        self
933    }
934}
935
936impl<S> ToSubstance<S> for Ping
937where
938    Substance: ToSubstance<S>,
939{
940    fn to_substance(self) -> Result<S, SpaceErr> {
941        self.core.to_substance()
942    }
943
944    fn to_substance_ref(&self) -> Result<&S, SpaceErr> {
945        self.core.to_substance_ref()
946    }
947}
948
949impl Deref for Ping {
950    type Target = DirectedCore;
951
952    fn deref(&self) -> &Self::Target {
953        &self.core
954    }
955}
956
957impl DerefMut for Ping {
958    fn deref_mut(&mut self) -> &mut Self::Target {
959        &mut self.core
960    }
961}
962
963impl Into<DirectedProto> for Wave<Ping> {
964    fn into(self) -> DirectedProto {
965        let mut core = self.core.clone();
966        DirectedProto {
967            to: Some(self.to.clone().to_recipients()),
968            method: None,
969            core,
970            id: self.id,
971            from: Some(self.from),
972            handling: Some(self.handling),
973            scope: Some(self.scope),
974            agent: Some(self.agent),
975            kind: None,
976            bounce_backs: None,
977            track: self.track,
978            via: self.via,
979            history: HashSet::new(),
980        }
981    }
982}
983
984impl Ping {
985    pub fn require_method<M: Into<Method> + ToString + Clone>(
986        self,
987        method: M,
988    ) -> Result<Ping, SpaceErr> {
989        if self.core.method == method.clone().into() {
990            Ok(self)
991        } else {
992            Err(SpaceErr::new(
993                400,
994                format!("Bad Request: expecting method: {}", method.to_string()).as_str(),
995            ))
996        }
997    }
998
999    pub fn require_body<B>(self) -> Result<B, SpaceErr>
1000    where
1001        B: TryFrom<Substance, Error = SpaceErr>,
1002    {
1003        match B::try_from(self.clone().core.body) {
1004            Ok(body) => Ok(body),
1005            Err(err) => Err(SpaceErr::bad_request("body is required")),
1006        }
1007    }
1008}
1009
1010#[derive(Serialize, Deserialize)]
1011pub struct WaveXtra<V> {
1012    pub wave: Wave<V>,
1013    pub session: Session,
1014}
1015
1016impl<V> WaveXtra<V> {
1017    pub fn new(wave: Wave<V>, session: Session) -> Self {
1018        Self { wave, session }
1019    }
1020}
1021
1022impl TryFrom<Ping> for RawCommand {
1023    type Error = SpaceErr;
1024
1025    fn try_from(request: Ping) -> Result<Self, Self::Error> {
1026        request.core.body.try_into()
1027    }
1028}
1029
1030impl TryFrom<Pong> for Substance {
1031    type Error = SpaceErr;
1032
1033    fn try_from(response: Pong) -> Result<Self, Self::Error> {
1034        Ok(response.core.body)
1035    }
1036}
1037
1038impl TryInto<Bin> for Pong {
1039    type Error = SpaceErr;
1040
1041    fn try_into(self) -> Result<Bin, Self::Error> {
1042        match self.core.body {
1043            Substance::Bin(bin) => Ok(bin),
1044            _ => Err(SpaceErr::bad_request("expected Bin")),
1045        }
1046    }
1047}
1048
1049impl Into<DirectedCore> for RawCommand {
1050    fn into(self) -> DirectedCore {
1051        DirectedCore::substance(
1052            ExtMethod::new("ExecCommand").unwrap().into(),
1053            Substance::RawCommand(self),
1054        )
1055    }
1056}
1057
1058impl Ping {
1059    pub fn new<P: ToSurface>(core: DirectedCore, to: P) -> Self {
1060        Self {
1061            to: to.to_surface(),
1062            core,
1063        }
1064    }
1065}
1066
1067#[derive(Clone, strum_macros::Display)]
1068pub enum ReflectedKind {
1069    Pong,
1070    Echo,
1071}
1072
1073#[derive(Clone, strum_macros::Display)]
1074pub enum DirectedKind {
1075    Ping,
1076    Ripple,
1077    Signal,
1078}
1079
1080#[derive(Clone)]
1081pub struct ReflectedProto {
1082    pub id: WaveId,
1083    pub intended: Option<Recipients>,
1084    pub from: Option<Surface>,
1085    pub to: Option<Surface>,
1086    pub body: Option<Substance>,
1087    pub status: Option<StatusCode>,
1088    pub handling: Option<Handling>,
1089    pub scope: Option<Scope>,
1090    pub agent: Option<Agent>,
1091    pub reflection_of: Option<WaveId>,
1092    pub kind: Option<ReflectedKind>,
1093    pub track: bool,
1094}
1095
1096impl ReflectedProto {
1097    pub fn new() -> Self {
1098        Self {
1099            id: WaveId::new(WaveKind::Echo),
1100            intended: None,
1101            from: None,
1102            to: None,
1103            body: None,
1104            status: None,
1105            handling: None,
1106            scope: None,
1107            agent: None,
1108            reflection_of: None,
1109            kind: None,
1110            track: false,
1111        }
1112    }
1113
1114    pub fn kind(&mut self, kind: ReflectedKind) {
1115        self.kind.replace(kind);
1116    }
1117
1118    pub fn fill<V>(&mut self, wave: &Wave<V>) {
1119        self.reflection_of = Some(wave.id.clone());
1120        self.fill_to(&wave.from);
1121        self.fill_handling(&wave.handling);
1122        self.fill_scope(&wave.scope);
1123        self.fill_agent(&wave.agent);
1124        self.reflection_of = Some(wave.id.clone());
1125    }
1126
1127    pub fn fill_kind(&mut self, kind: ReflectedKind) {
1128        if self.kind.is_none() {
1129            self.kind.replace(kind);
1130        }
1131    }
1132
1133    pub fn fill_intended<I: ToRecipients + Clone>(&mut self, intended: I) {
1134        if self.intended.is_none() {
1135            self.intended.replace(intended.to_recipients());
1136        }
1137    }
1138
1139    pub fn fill_to(&mut self, to: &Surface) {
1140        if self.to.is_none() {
1141            self.to.replace(to.clone());
1142        }
1143    }
1144
1145    pub fn fill_from(&mut self, from: &Surface) {
1146        if self.from.is_none() {
1147            self.from.replace(from.clone());
1148        }
1149    }
1150
1151    pub fn fill_scope(&mut self, scope: &Scope) {
1152        if self.scope.is_none() {
1153            self.scope.replace(scope.clone());
1154        }
1155    }
1156
1157    pub fn fill_agent(&mut self, agent: &Agent) {
1158        if self.agent.is_none() {
1159            self.agent.replace(agent.clone());
1160        }
1161    }
1162
1163    pub fn fill_handling(&mut self, handling: &Handling) {
1164        if self.handling.is_none() {
1165            self.handling.replace(handling.clone());
1166        }
1167    }
1168
1169    pub fn fill_status(&mut self, status: &StatusCode) {
1170        if self.status.is_none() {
1171            self.status.replace(status.clone());
1172        }
1173    }
1174
1175    pub fn body(&mut self, body: Substance) -> Result<(), SpaceErr> {
1176        self.body.replace(body);
1177        Ok(())
1178    }
1179
1180    pub fn intended<I: ToRecipients + Clone>(&mut self, intended: I) {
1181        self.intended.replace(intended.to_recipients());
1182    }
1183
1184    pub fn reflection_of(&mut self, id: WaveId) {
1185        self.reflection_of.replace(id);
1186    }
1187
1188    pub fn status(&mut self, status: u16) {
1189        self.status
1190            .replace(StatusCode::from_u16(status).unwrap_or(StatusCode::from_u16(500).unwrap()));
1191    }
1192
1193    pub fn to(&mut self, to: Surface) {
1194        self.to.replace(to.clone());
1195    }
1196
1197    pub fn scope(&mut self, scope: Scope) {
1198        self.scope.replace(scope);
1199    }
1200
1201    pub fn agent(&mut self, agent: Agent) {
1202        self.agent.replace(agent);
1203    }
1204
1205    pub fn handling(&mut self, handling: Handling) {
1206        self.handling.replace(handling);
1207    }
1208
1209    pub fn from(&mut self, from: Surface) {
1210        self.from.replace(from);
1211    }
1212
1213    pub fn build(self) -> Result<ReflectedWave, SpaceErr> {
1214        let mut core = ReflectedCore::new();
1215        core.body = self.body.or_else(|| Some(Substance::Empty)).unwrap();
1216        core.status = self
1217            .status
1218            .or_else(|| Some(StatusCode::from_u16(200u16).unwrap()))
1219            .unwrap();
1220        match self.kind.ok_or("missing ReflectedWave Kind")? {
1221            ReflectedKind::Pong => {
1222                let mut pong = Wave::new(
1223                    Pong::new(
1224                        core,
1225                        self.to.ok_or("ReflectedProto missing to")?,
1226                        self.intended.ok_or("Reflected Proto Missing intended")?,
1227                        self.reflection_of.ok_or("response to expected")?,
1228                    ),
1229                    self.from.ok_or("expected from")?,
1230                );
1231                pong.track = self.track;
1232                Ok(pong.to_reflected())
1233            }
1234            ReflectedKind::Echo => {
1235                let mut echo = Wave::new(
1236                    Echo::new(
1237                        core,
1238                        self.to.ok_or("ReflectedProto missing to")?,
1239                        self.intended.ok_or("Reflected Proto Missing intended")?,
1240                        self.reflection_of.ok_or("response to expected")?,
1241                    ),
1242                    self.from.ok_or("expected from")?,
1243                );
1244                echo.track = self.track;
1245                Ok(echo.to_reflected())
1246            }
1247        }
1248    }
1249}
1250
1251#[derive(Clone)]
1252pub struct DirectedProto {
1253    pub id: WaveId,
1254    pub from: Option<Surface>,
1255    pub to: Option<Recipients>,
1256    pub core: DirectedCore,
1257    pub method: Option<Method>,
1258    pub handling: Option<Handling>,
1259    pub scope: Option<Scope>,
1260    pub agent: Option<Agent>,
1261    pub kind: Option<DirectedKind>,
1262    pub bounce_backs: Option<BounceBacks>,
1263    pub via: Option<Surface>,
1264    pub track: bool,
1265    pub history: HashSet<Point>,
1266}
1267impl Trackable for DirectedProto {
1268    fn track_id(&self) -> String {
1269        self.id.to_short_string()
1270    }
1271
1272    fn track_method(&self) -> String {
1273        self.core.method.to_deep_string()
1274    }
1275
1276    fn track_payload(&self) -> String {
1277        self.core.body.to_string()
1278    }
1279
1280    fn track_from(&self) -> String {
1281        match &self.from {
1282            None => "None".to_string(),
1283            Some(from) => from.to_string(),
1284        }
1285    }
1286
1287    fn track_to(&self) -> String {
1288        match &self.to {
1289            None => "None".to_string(),
1290            Some(to) => to.to_string(),
1291        }
1292    }
1293
1294    fn track(&self) -> bool {
1295        self.track
1296    }
1297}
1298
1299impl DirectedProto {
1300    pub fn build(self) -> Result<DirectedWave, SpaceErr> {
1301        let kind = self.kind.ok_or::<SpaceErr>(
1302            "kind must be set for DirectedProto to create the proper DirectedWave".into(),
1303        )?;
1304
1305        let mut core = self.core.clone();
1306        if let Some(method) = self.method {
1307            core.method = method;
1308        }
1309
1310        let mut wave = match kind {
1311            DirectedKind::Ping => {
1312                let mut wave = Wave::new(
1313                    Ping {
1314                        to: self
1315                            .to
1316                            .ok_or(SpaceErr::new(500u16, "must set 'to'"))?
1317                            .single_or()?,
1318                        core,
1319                    },
1320                    self.from.ok_or(SpaceErr::new(500u16, "must set 'from'"))?,
1321                );
1322                wave.agent = self.agent.unwrap_or_else(|| Agent::Anonymous);
1323                wave.handling = self.handling.unwrap_or_else(|| Handling::default());
1324                wave.scope = self.scope.unwrap_or_else(|| Scope::None);
1325                wave.via = self.via;
1326                wave.track = self.track;
1327                wave.to_directed()
1328            }
1329            DirectedKind::Ripple => {
1330                let mut wave = Wave::new(
1331                    Ripple {
1332                        to: self.to.ok_or(SpaceErr::new(500u16, "must set 'to'"))?,
1333                        core,
1334                        bounce_backs: self.bounce_backs.ok_or("BounceBacks must be set")?,
1335                        history: self.history,
1336                    },
1337                    self.from.ok_or(SpaceErr::new(500u16, "must set 'from'"))?,
1338                );
1339                wave.agent = self.agent.unwrap_or_else(|| Agent::Anonymous);
1340                wave.handling = self.handling.unwrap_or_else(|| Handling::default());
1341                wave.scope = self.scope.unwrap_or_else(|| Scope::None);
1342                wave.via = self.via;
1343                wave.track = self.track;
1344                wave.to_directed()
1345            }
1346            DirectedKind::Signal => {
1347                let mut wave = Wave::new(
1348                    Signal {
1349                        to: self
1350                            .to
1351                            .ok_or(SpaceErr::new(500u16, "must set 'to'"))?
1352                            .single_or()?,
1353                        core,
1354                    },
1355                    self.from.ok_or(SpaceErr::new(500u16, "must set 'from'"))?,
1356                );
1357                wave.agent = self.agent.unwrap_or_else(|| Agent::Anonymous);
1358                wave.handling = self.handling.unwrap_or_else(|| Handling::default());
1359                wave.scope = self.scope.unwrap_or_else(|| Scope::None);
1360                wave.via = self.via;
1361                wave.track = self.track;
1362                wave.to_directed()
1363            }
1364        };
1365
1366        Ok(wave)
1367    }
1368
1369    pub fn fill(&mut self, wave: &UltraWave) {
1370        self.fill_handling(wave.handling());
1371        self.fill_scope(wave.scope());
1372        self.fill_agent(wave.agent());
1373    }
1374
1375    pub fn fill_kind(&mut self, kind: DirectedKind) {
1376        if self.kind.is_none() {
1377            self.kind.replace(kind);
1378        }
1379    }
1380
1381    pub fn fill_to<R: ToRecipients + Clone>(&mut self, to: R) {
1382        if self.to.is_none() {
1383            self.to.replace(to.to_recipients());
1384        }
1385    }
1386
1387    pub fn fill_from<P: ToSurface>(&mut self, from: P) {
1388        if self.from.is_none() {
1389            self.from.replace(from.to_surface());
1390        }
1391    }
1392
1393    pub fn fill_scope(&mut self, scope: &Scope) {
1394        if self.scope.is_none() {
1395            self.scope.replace(scope.clone());
1396        }
1397    }
1398
1399    pub fn fill_agent(&mut self, agent: &Agent) {
1400        if self.agent.is_none() {
1401            self.agent.replace(agent.clone());
1402        }
1403    }
1404
1405    pub fn fill_handling(&mut self, handling: &Handling) {
1406        if self.handling.is_none() {
1407            self.handling.replace(handling.clone());
1408        }
1409    }
1410
1411    pub fn fill_method(&mut self, method: &Method) {
1412        if self.method.is_none() {
1413            self.method.replace(method.clone());
1414        }
1415    }
1416
1417    pub fn agent(&mut self, agent: Agent) {
1418        self.agent.replace(agent);
1419    }
1420
1421    pub fn bounce_backs(&mut self, bounce_backs: BounceBacks) {
1422        self.bounce_backs.replace(bounce_backs);
1423    }
1424
1425    pub fn scope(&mut self, scope: Scope) {
1426        self.scope.replace(scope);
1427    }
1428
1429    pub fn handling(&mut self, handling: Handling) {
1430        self.handling.replace(handling);
1431    }
1432
1433    pub fn kind(kind: &DirectedKind) -> Self {
1434        match kind {
1435            DirectedKind::Ping => Self::ping(),
1436            DirectedKind::Ripple => Self::ripple(),
1437            DirectedKind::Signal => Self::signal(),
1438        }
1439    }
1440
1441    pub fn body(&mut self, body: Substance) {
1442        self.core.body = body;
1443    }
1444
1445    pub fn history(&mut self, history: HashSet<Point>) {
1446        self.history = history;
1447    }
1448
1449    pub fn uri(&mut self, uri: Url) {
1450        self.core.uri = uri;
1451    }
1452
1453    pub fn core(&mut self, core: DirectedCore) -> Result<(), SpaceErr> {
1454        self.core = core;
1455        Ok(())
1456    }
1457
1458    pub fn method<M: Into<Method> + Clone>(&mut self, method: M) {
1459        self.method.replace(method.clone().into());
1460        self.core.method = method.into();
1461    }
1462
1463    pub fn to<P: ToRecipients + Clone>(&mut self, to: P) {
1464        self.to.replace(to.to_recipients());
1465    }
1466
1467    pub fn from<P: ToSurface>(&mut self, from: P) {
1468        self.from.replace(from.to_surface());
1469    }
1470
1471    pub fn fill_via<P: ToSurface>(&mut self, via: P) {
1472        if self.via.is_none() {
1473            self.via.replace(via.to_surface());
1474        }
1475    }
1476
1477    pub fn via<P: ToSurface>(&mut self, via: &P) {
1478        self.via.replace(via.to_surface());
1479    }
1480}
1481
1482impl DirectedProto {
1483    pub fn ping() -> Self {
1484        Self {
1485            id: WaveId::new(WaveKind::Ping),
1486            kind: Some(DirectedKind::Ping),
1487            bounce_backs: Some(BounceBacks::Single),
1488            ..DirectedProto::default()
1489        }
1490    }
1491
1492    pub fn signal() -> Self {
1493        Self {
1494            id: WaveId::new(WaveKind::Signal),
1495            kind: Some(DirectedKind::Signal),
1496            bounce_backs: Some(BounceBacks::None),
1497            ..DirectedProto::default()
1498        }
1499    }
1500
1501    pub fn ripple() -> Self {
1502        Self {
1503            id: WaveId::new(WaveKind::Ripple),
1504            kind: Some(DirectedKind::Ripple),
1505            ..DirectedProto::default()
1506        }
1507    }
1508
1509    pub fn to_with_method<P: ToRecipients + Clone>(to: P, method: Method) -> Self {
1510        Self {
1511            id: WaveId::new(WaveKind::Ping),
1512            to: Some(to.to_recipients()),
1513            kind: Some(DirectedKind::Ping),
1514            core: DirectedCore::new(method),
1515            ..DirectedProto::default()
1516        }
1517    }
1518
1519    pub fn from_core(core: DirectedCore) -> Self {
1520        Self {
1521            id: WaveId::new(WaveKind::Ping),
1522            kind: Some(DirectedKind::Ping),
1523            core,
1524            ..DirectedProto::default()
1525        }
1526    }
1527
1528    pub fn sys<M: Into<HypMethod>, P: ToRecipients + Clone>(to: P, method: M) -> Self {
1529        let method: HypMethod = method.into();
1530        let method: Method = method.into();
1531        Self::to_with_method(to, method)
1532    }
1533
1534    pub fn msg<M: Into<ExtMethod>, P: ToRecipients + Clone>(to: P, method: M) -> Self {
1535        let method: ExtMethod = method.into();
1536        let method: Method = method.into();
1537        Self::to_with_method(to, method)
1538    }
1539
1540    pub fn http<M: Into<HttpMethod>, P: ToRecipients + Clone>(to: P, method: M) -> Self {
1541        let method: HttpMethod = method.into();
1542        let method: Method = method.into();
1543        Self::to_with_method(to, method)
1544    }
1545
1546    pub fn cmd<M: Into<CmdMethod>, P: ToRecipients + Clone>(to: P, method: M) -> Self {
1547        let method: CmdMethod = method.into();
1548        let method: Method = method.into();
1549        Self::to_with_method(to, method)
1550    }
1551}
1552
1553impl Default for DirectedProto {
1554    fn default() -> Self {
1555        Self {
1556            id: WaveId::new(WaveKind::Ping),
1557            method: None,
1558            core: DirectedCore::default(),
1559            from: None,
1560            to: None,
1561            handling: None,
1562            scope: None,
1563            agent: None,
1564            kind: None,
1565            bounce_backs: None,
1566            via: None,
1567            track: false,
1568            history: Default::default(),
1569        }
1570    }
1571}
1572
1573pub type Echoes = Vec<Wave<Echo>>;
1574
1575impl FromReflectedAggregate for () {
1576    fn from_reflected_aggregate(agg: ReflectedAggregate) -> Result<Self, SpaceErr>
1577    where
1578        Self: Sized,
1579    {
1580        match agg {
1581            ReflectedAggregate::None => Ok(()),
1582            _ => Err(SpaceErr::bad_request(
1583                "expected a ReflectedAggregate of None",
1584            )),
1585        }
1586    }
1587}
1588
1589impl FromReflectedAggregate for Echoes {
1590    fn from_reflected_aggregate(agg: ReflectedAggregate) -> Result<Self, SpaceErr>
1591    where
1592        Self: Sized,
1593    {
1594        match agg {
1595            ReflectedAggregate::Multi(reflected) => {
1596                let mut echoes = Echoes::new();
1597                for r in reflected {
1598                    let echo: Wave<Echo> = r.to_echo()?;
1599                    echoes.push(echo);
1600                }
1601                Ok(echoes)
1602            }
1603            _ => Err(SpaceErr::bad_request(
1604                "expecting a ReflectedAggregate of Multi",
1605            )),
1606        }
1607    }
1608}
1609
1610#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
1611pub struct Echo {
1612    /// this is meant to be the intended request recipient, which may not be the point responding
1613    /// to this message in the case it was intercepted and filtered at some point
1614    pub to: Surface,
1615    pub intended: Recipients,
1616    pub core: ReflectedCore,
1617    pub reflection_of: WaveId,
1618}
1619
1620impl<S> ToSubstance<S> for Echo
1621where
1622    Substance: ToSubstance<S>,
1623{
1624    fn to_substance(self) -> Result<S, SpaceErr> {
1625        self.core.to_substance()
1626    }
1627
1628    fn to_substance_ref(&self) -> Result<&S, SpaceErr> {
1629        self.core.to_substance_ref()
1630    }
1631}
1632
1633impl Echo {
1634    pub fn is_ok(&self) -> bool {
1635        self.core.is_ok()
1636    }
1637
1638    pub fn core<E>(result: Result<Wave<Pong>, E>) -> ReflectedCore {
1639        match result {
1640            Ok(reflected) => reflected.variant.core,
1641            Err(err) => ReflectedCore::server_error(),
1642        }
1643    }
1644
1645    pub fn as_result<E: From<&'static str>, P: TryFrom<Substance>>(self) -> Result<P, E> {
1646        self.core.as_result()
1647    }
1648}
1649
1650impl Echo {
1651    pub fn new(
1652        core: ReflectedCore,
1653        to: Surface,
1654        intended: Recipients,
1655        reflection_of: WaveId,
1656    ) -> Self {
1657        Self {
1658            to,
1659            intended,
1660            core,
1661            reflection_of,
1662        }
1663    }
1664
1665    pub fn ok_or(self) -> Result<Self, SpaceErr> {
1666        if self.core.status.is_success() {
1667            Ok(self)
1668        } else {
1669            if let Substance::Text(error) = self.core.body {
1670                Err(error.into())
1671            } else {
1672                Err(format!("error code: {}", self.core.status.to_string()).into())
1673            }
1674        }
1675    }
1676}
1677
1678#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
1679pub struct Pong {
1680    /// this is meant to be the intended request recipient, which may not be the point responding
1681    /// to this message in the case it was intercepted and filtered at some point
1682    pub to: Surface,
1683    pub intended: Recipients,
1684    pub core: ReflectedCore,
1685    pub reflection_of: WaveId,
1686}
1687
1688impl FromReflectedAggregate for Wave<Pong> {
1689    fn from_reflected_aggregate(agg: ReflectedAggregate) -> Result<Self, SpaceErr>
1690    where
1691        Self: Sized,
1692    {
1693        match agg {
1694            ReflectedAggregate::Single(reflected) => match reflected {
1695                ReflectedWave::Pong(pong) => Ok(pong),
1696                _ => Err(SpaceErr::bad_request("expected a Pong Reflected")),
1697            },
1698            ReflectedAggregate::None => Err(SpaceErr::bad_request(
1699                "expected a Single Reflected, encountered: None",
1700            )),
1701            ReflectedAggregate::Multi(_) => Err(SpaceErr::bad_request(
1702                "expected a Single Reflected, encountered: Multi",
1703            )),
1704        }
1705    }
1706}
1707
1708impl<S> ToSubstance<S> for Pong
1709where
1710    Substance: ToSubstance<S>,
1711{
1712    fn to_substance(self) -> Result<S, SpaceErr> {
1713        self.core.to_substance()
1714    }
1715
1716    fn to_substance_ref(&self) -> Result<&S, SpaceErr> {
1717        self.core.to_substance_ref()
1718    }
1719}
1720
1721impl Pong {
1722    pub fn is_ok(&self) -> bool {
1723        self.core.is_ok()
1724    }
1725
1726    pub fn core<E>(result: Result<Wave<Pong>, E>) -> ReflectedCore {
1727        match result {
1728            Ok(reflected) => reflected.variant.core,
1729            Err(err) => ReflectedCore::server_error(),
1730        }
1731    }
1732
1733    pub fn as_result<E: From<&'static str>, P: TryFrom<Substance>>(self) -> Result<P, E> {
1734        self.core.as_result()
1735    }
1736
1737    pub fn ok_or(&self) -> Result<(), SpaceErr> {
1738        if self.is_ok() {
1739            Ok(())
1740        } else {
1741            if let Substance::FormErrs(errs) = &self.core.body {
1742                Err(format!("{} : {}", self.core.status.to_string(), errs.to_string()).into())
1743            } else if let Substance::Err(err) = &self.core.body {
1744                Err(err.clone())
1745            } else {
1746                Err(self.core.status.to_string().into())
1747            }
1748        }
1749    }
1750}
1751
1752impl Pong {
1753    pub fn new(
1754        core: ReflectedCore,
1755        to: Surface,
1756        intended: Recipients,
1757        reflection_of: WaveId,
1758    ) -> Self {
1759        Self {
1760            to,
1761            intended,
1762            core,
1763            reflection_of,
1764        }
1765    }
1766}
1767
1768pub struct RecipientSelector<'a> {
1769    pub to: &'a Surface,
1770    pub wave: &'a DirectedWave,
1771}
1772
1773impl<'a> RecipientSelector<'a> {
1774    pub fn new(to: &'a Surface, wave: &'a Wave<DirectedWave>) -> Self {
1775        Self { to, wave }
1776    }
1777}
1778
1779pub type DirectedWave = DirectedWaveDef<Recipients>;
1780pub type SingularDirectedWave = DirectedWaveDef<Surface>;
1781
1782impl Into<DirectedProto> for DirectedWave {
1783    fn into(self) -> DirectedProto {
1784        let mut proto = DirectedProto {
1785            id: self.id().clone(),
1786            kind: Some(self.directed_kind()),
1787            ..DirectedProto::default()
1788        };
1789        proto.id = self.id().clone();
1790        proto.core(self.core().clone());
1791        proto.to(self.to());
1792        proto.from(self.from().clone());
1793        proto.agent(self.agent().clone());
1794        proto.scope(self.scope().clone());
1795        proto.handling(self.handling().clone());
1796        proto.track = self.track();
1797        proto.bounce_backs(self.bounce_backs());
1798        proto.agent(self.agent().clone());
1799        if let Some(via) = self.via() {
1800            proto.via(via);
1801        }
1802        proto
1803    }
1804}
1805
1806impl Trackable for DirectedWave {
1807    fn track_id(&self) -> String {
1808        self.id().to_short_string()
1809    }
1810
1811    fn track_method(&self) -> String {
1812        match self {
1813            Self::Ping(ping) => ping.core.method.to_deep_string(),
1814            Self::Ripple(ripple) => ripple.core.method.to_deep_string(),
1815            Self::Signal(signal) => signal.core.method.to_deep_string(),
1816        }
1817    }
1818
1819    fn track_payload(&self) -> String {
1820        match self {
1821            Self::Ping(ping) => ping.core.body.kind().to_string(),
1822            Self::Ripple(ripple) => ripple.core.body.kind().to_string(),
1823            Self::Signal(signal) => signal.core.body.kind().to_string(),
1824        }
1825    }
1826
1827    fn track_from(&self) -> String {
1828        self.from().to_string()
1829    }
1830
1831    fn track_to(&self) -> String {
1832        self.to().to_string()
1833    }
1834
1835    fn track(&self) -> bool {
1836        match self {
1837            Self::Ping(ping) => ping.track,
1838            Self::Ripple(ripple) => ripple.track,
1839            Self::Signal(signal) => signal.track,
1840        }
1841    }
1842    fn track_payload_fmt(&self) -> String {
1843        match self {
1844            Self::Signal(signal) => signal.track_payload_fmt(),
1845            Self::Ping(ping) => ping.track_payload_fmt(),
1846            Self::Ripple(_) => self.track_payload(),
1847        }
1848    }
1849}
1850
1851#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
1852pub enum DirectedWaveDef<T>
1853where
1854    T: ToRecipients + Clone,
1855{
1856    Ping(Wave<Ping>),
1857    Ripple(Wave<RippleDef<T>>),
1858    Signal(Wave<Signal>),
1859}
1860
1861impl<T> DirectedWaveDef<T>
1862where
1863    T: ToRecipients + Clone,
1864{
1865    pub fn kind(&self) -> WaveKind {
1866        match self {
1867            DirectedWaveDef::Ping(_) => WaveKind::Ping,
1868            DirectedWaveDef::Ripple(_) => WaveKind::Ripple,
1869            DirectedWaveDef::Signal(_) => WaveKind::Signal,
1870        }
1871    }
1872
1873    pub fn has_visited(&self, star: &Point) -> bool {
1874        match self {
1875            Self::Ripple(ripple) => ripple.history.contains(star),
1876            _ => false,
1877        }
1878    }
1879
1880    pub fn add_history(&mut self, point: &Point) {
1881        match self {
1882            Self::Ping(_) => {}
1883            Self::Ripple(ripple) => {
1884                ripple.history.insert(point.clone());
1885            }
1886            Self::Signal(_) => {}
1887        }
1888    }
1889
1890    pub fn history(&self) -> HashSet<Point> {
1891        match self {
1892            Self::Ping(_) => HashSet::new(),
1893            Self::Ripple(ripple) => ripple.history.clone(),
1894            Self::Signal(_) => HashSet::new(),
1895        }
1896    }
1897}
1898
1899impl<W> Spannable for DirectedWaveDef<W>
1900where
1901    W: ToRecipients + Clone,
1902{
1903    fn span_id(&self) -> String {
1904        self.id().to_string()
1905    }
1906
1907    fn span_type(&self) -> &'static str {
1908        "Wave"
1909    }
1910}
1911
1912impl DirectedWave {
1913    pub fn to(&self) -> Recipients {
1914        match self {
1915            Self::Ping(ping) => ping.to.clone().to_recipients(),
1916            Self::Ripple(ripple) => ripple.to.clone(),
1917            Self::Signal(signal) => signal.to.clone().to_recipients(),
1918        }
1919    }
1920
1921    pub fn hops(&self) -> u16 {
1922        match self {
1923            DirectedWave::Ping(ping) => ping.hops.clone(),
1924            DirectedWave::Ripple(ripple) => ripple.hops.clone(),
1925            DirectedWave::Signal(signal) => signal.hops.clone(),
1926        }
1927    }
1928
1929    pub fn is_signal(&self) -> bool {
1930        match self {
1931            DirectedWave::Signal(_) => true,
1932            _ => false,
1933        }
1934    }
1935
1936    pub fn reflection(&self) -> Result<Reflection, SpaceErr> {
1937        Ok(Reflection {
1938            kind: match self {
1939                DirectedWave::Ping(_) => ReflectedKind::Pong,
1940                DirectedWave::Ripple(_) => ReflectedKind::Echo,
1941                DirectedWave::Signal(_) => return Err("signals do not have a reflected".into()),
1942            },
1943            to: self.reflect_to().clone(),
1944            intended: self.to(),
1945            reflection_of: self.id().clone(),
1946            track: self.track(),
1947        })
1948    }
1949
1950    pub fn to_signal(self) -> Result<Wave<Signal>, SpaceErr> {
1951        match self {
1952            DirectedWave::Signal(signal) => Ok(signal),
1953            _ => Err("not a signal wave".into()),
1954        }
1955    }
1956
1957    pub fn to_call(&self, to: Surface) -> Result<Call, SpaceErr> {
1958        let kind = match &self.core().method {
1959            Method::Cmd(method) => CallKind::Cmd(CmdCall::new(
1960                method.clone(),
1961                Subst::new(self.core().uri.path())?,
1962            )),
1963            Method::Hyp(method) => CallKind::Hyp(HypCall::new(
1964                method.clone(),
1965                Subst::new(self.core().uri.path())?,
1966            )),
1967            Method::Http(method) => CallKind::Http(HttpCall::new(
1968                method.clone(),
1969                Subst::new(self.core().uri.path())?,
1970            )),
1971            Method::Ext(method) => CallKind::Ext(ExtCall::new(
1972                method.clone(),
1973                Subst::new(self.core().uri.path())?,
1974            )),
1975        };
1976
1977        Ok(Call {
1978            point: to.point,
1979            kind,
1980        })
1981    }
1982}
1983
1984impl Trackable for SingularDirectedWave {
1985    fn track_id(&self) -> String {
1986        self.id().to_short_string()
1987    }
1988
1989    fn track_method(&self) -> String {
1990        match self {
1991            Self::Ping(ping) => ping.core.method.to_deep_string(),
1992            Self::Ripple(ripple) => ripple.core.method.to_deep_string(),
1993            Self::Signal(signal) => signal.core.method.to_deep_string(),
1994        }
1995    }
1996
1997    fn track_payload(&self) -> String {
1998        match self {
1999            Self::Ping(ping) => ping.core.body.kind().to_string(),
2000            Self::Ripple(ripple) => ripple.core.body.kind().to_string(),
2001            Self::Signal(signal) => signal.core.body.kind().to_string(),
2002        }
2003    }
2004
2005    fn track_from(&self) -> String {
2006        self.from().to_string()
2007    }
2008
2009    fn track_to(&self) -> String {
2010        self.to().to_string()
2011    }
2012
2013    fn track(&self) -> bool {
2014        match self {
2015            Self::Ping(ping) => ping.track,
2016            Self::Ripple(ripple) => ripple.track,
2017            Self::Signal(signal) => signal.track,
2018        }
2019    }
2020    fn track_payload_fmt(&self) -> String {
2021        match self {
2022            Self::Signal(signal) => signal.track_payload_fmt(),
2023            Self::Ping(ping) => ping.track_payload_fmt(),
2024            Self::Ripple(_) => self.track_payload(),
2025        }
2026    }
2027}
2028impl SingularDirectedWave {
2029    pub fn to(&self) -> Surface {
2030        match self {
2031            Self::Ping(ping) => ping.to.clone(),
2032            Self::Ripple(ripple) => ripple.to.clone(),
2033            Self::Signal(signal) => signal.to.clone(),
2034        }
2035    }
2036
2037    pub fn to_call(&self) -> Result<Call, SpaceErr> {
2038        let kind = match &self.core().method {
2039            Method::Cmd(method) => CallKind::Cmd(CmdCall::new(
2040                method.clone(),
2041                Subst::new(self.core().uri.path())?,
2042            )),
2043            Method::Hyp(method) => CallKind::Hyp(HypCall::new(
2044                method.clone(),
2045                Subst::new(self.core().uri.path())?,
2046            )),
2047            Method::Http(method) => CallKind::Http(HttpCall::new(
2048                method.clone(),
2049                Subst::new(self.core().uri.path())?,
2050            )),
2051            Method::Ext(method) => CallKind::Ext(ExtCall::new(
2052                method.clone(),
2053                Subst::new(self.core().uri.path())?,
2054            )),
2055        };
2056
2057        Ok(Call {
2058            point: self.to().clone().to_point(),
2059            kind,
2060        })
2061    }
2062
2063    pub fn reflection(&self) -> Result<Reflection, SpaceErr> {
2064        Ok(Reflection {
2065            kind: match self {
2066                SingularDirectedWave::Ping(_) => ReflectedKind::Pong,
2067                SingularDirectedWave::Ripple(_) => ReflectedKind::Echo,
2068                SingularDirectedWave::Signal(_) => {
2069                    return Err("signals do not have a reflected".into())
2070                }
2071            },
2072            to: self.from().clone(),
2073            intended: self.to().to_recipients(),
2074            reflection_of: self.id().clone(),
2075            track: self.track(),
2076        })
2077    }
2078
2079    pub fn to_ultra(self) -> UltraWave {
2080        match self {
2081            SingularDirectedWave::Ping(ping) => UltraWave::Ping(ping),
2082            SingularDirectedWave::Signal(signal) => UltraWave::Signal(signal),
2083            SingularDirectedWave::Ripple(ripple) => UltraWave::Ripple(ripple.to_multiple()),
2084        }
2085    }
2086}
2087
2088impl<T> DirectedWaveDef<T>
2089where
2090    T: ToRecipients + Clone,
2091{
2092    pub fn id(&self) -> &WaveId {
2093        match self {
2094            DirectedWaveDef::Ping(ping) => &ping.id,
2095            DirectedWaveDef::Ripple(ripple) => &ripple.id,
2096            DirectedWaveDef::Signal(signal) => &signal.id,
2097        }
2098    }
2099
2100    pub fn agent(&self) -> &Agent {
2101        match self {
2102            DirectedWaveDef::Ping(ping) => &ping.agent,
2103            DirectedWaveDef::Ripple(ripple) => &ripple.agent,
2104            DirectedWaveDef::Signal(signal) => &signal.agent,
2105        }
2106    }
2107
2108    pub fn scope(&self) -> &Scope {
2109        match self {
2110            DirectedWaveDef::Ping(ping) => &ping.scope,
2111            DirectedWaveDef::Ripple(ripple) => &ripple.scope,
2112            DirectedWaveDef::Signal(signal) => &signal.scope,
2113        }
2114    }
2115
2116    pub fn handling(&self) -> &Handling {
2117        match self {
2118            DirectedWaveDef::Ping(ping) => &ping.handling,
2119            DirectedWaveDef::Ripple(ripple) => &ripple.handling,
2120            DirectedWaveDef::Signal(signal) => &signal.handling,
2121        }
2122    }
2123
2124    pub fn err(&self, err: SpaceErr, responder: Surface) -> Bounce<ReflectedWave> {
2125        match self {
2126            DirectedWaveDef::Ping(ping) => {
2127                Bounce::Reflected(ping.err(err, responder).to_reflected())
2128            }
2129            DirectedWaveDef::Ripple(ripple) => {
2130                Bounce::Reflected(ripple.err(err, responder).to_reflected())
2131            }
2132            DirectedWaveDef::Signal(_) => Bounce::Absorbed,
2133        }
2134    }
2135
2136    pub fn bounce_backs(&self) -> BounceBacks {
2137        match self {
2138            DirectedWaveDef::Ping(ping) => ping.bounce_backs(),
2139            DirectedWaveDef::Ripple(ripple) => ripple.bounce_backs(),
2140            DirectedWaveDef::Signal(signal) => signal.bounce_backs(),
2141        }
2142    }
2143
2144    pub fn set_bounce_backs(&mut self, bounce_backs: BounceBacks) -> Result<(), SpaceErr> {
2145        match self {
2146            DirectedWaveDef::Ripple(ripple) => {
2147                ripple.bounce_backs = bounce_backs;
2148                Ok(())
2149            }
2150            _ => Err(SpaceErr::server_error(
2151                "can only set bouncebacks for Ripple",
2152            )),
2153        }
2154    }
2155
2156    pub fn from(&self) -> &Surface {
2157        match self {
2158            DirectedWaveDef::Ping(ping) => &ping.from,
2159            DirectedWaveDef::Ripple(ripple) => &ripple.from,
2160            DirectedWaveDef::Signal(signal) => &signal.from,
2161        }
2162    }
2163
2164    pub fn via(&self) -> &Option<Surface> {
2165        match self {
2166            DirectedWaveDef::Ping(ping) => &ping.via,
2167            DirectedWaveDef::Ripple(ripple) => &ripple.via,
2168            DirectedWaveDef::Signal(signal) => &signal.via,
2169        }
2170    }
2171
2172    pub fn reflect_to(&self) -> &Surface {
2173        self.via().as_ref().unwrap_or(self.from())
2174    }
2175
2176    pub fn take_via(&mut self) -> Option<Surface> {
2177        match self {
2178            DirectedWaveDef::Ping(ping) => ping.via.take(),
2179            DirectedWaveDef::Ripple(ripple) => ripple.via.take(),
2180            DirectedWaveDef::Signal(signal) => signal.via.take(),
2181        }
2182    }
2183
2184    pub fn replace_via(&mut self, surface: Surface) -> Option<Surface> {
2185        match self {
2186            DirectedWaveDef::Ping(ping) => ping.via.replace(surface),
2187            DirectedWaveDef::Ripple(ripple) => ripple.via.replace(surface),
2188            DirectedWaveDef::Signal(signal) => signal.via.replace(surface),
2189        }
2190    }
2191
2192    pub fn body(&self) -> &Substance {
2193        match self {
2194            DirectedWaveDef::Ping(ping) => &ping.core.body,
2195            DirectedWaveDef::Ripple(ripple) => &ripple.core.body,
2196            DirectedWaveDef::Signal(signal) => &signal.core.body,
2197        }
2198    }
2199
2200    pub fn directed_kind(&self) -> DirectedKind {
2201        match self {
2202            DirectedWaveDef::Ping(_) => DirectedKind::Ping,
2203            DirectedWaveDef::Ripple(_) => DirectedKind::Ripple,
2204            DirectedWaveDef::Signal(_) => DirectedKind::Signal,
2205        }
2206    }
2207
2208    pub fn core(&self) -> &DirectedCore {
2209        match self {
2210            DirectedWaveDef::Ping(ping) => &ping.core,
2211            DirectedWaveDef::Ripple(ripple) => &ripple.core,
2212            DirectedWaveDef::Signal(signal) => &signal.core,
2213        }
2214    }
2215
2216    pub fn core_mut(&mut self) -> &mut DirectedCore {
2217        match self {
2218            DirectedWaveDef::Ping(ping) => &mut ping.core,
2219            DirectedWaveDef::Ripple(ripple) => &mut ripple.core,
2220            DirectedWaveDef::Signal(signal) => &mut signal.core,
2221        }
2222    }
2223}
2224
2225#[derive(Clone)]
2226pub struct Reflection {
2227    pub kind: ReflectedKind,
2228    pub to: Surface,
2229    pub intended: Recipients,
2230    pub reflection_of: WaveId,
2231    pub track: bool,
2232}
2233
2234impl Reflection {
2235    pub fn make(self, core: ReflectedCore, from: Surface) -> ReflectedWave {
2236        match self.kind {
2237            ReflectedKind::Pong => {
2238                let mut wave = Wave::new(
2239                    Pong::new(core, self.to, self.intended, self.reflection_of),
2240                    from,
2241                );
2242                wave.track = self.track;
2243                wave.to_reflected()
2244            }
2245            ReflectedKind::Echo => {
2246                let mut wave = Wave::new(
2247                    Echo::new(core, self.to, self.intended, self.reflection_of),
2248                    from,
2249                );
2250                wave.track = self.track;
2251                wave.to_reflected()
2252            }
2253        }
2254    }
2255}
2256
2257impl<S> ToSubstance<S> for DirectedWave
2258where
2259    Substance: ToSubstance<S>,
2260{
2261    fn to_substance(self) -> Result<S, SpaceErr> {
2262        match self {
2263            DirectedWave::Ping(ping) => ping.to_substance(),
2264            DirectedWave::Ripple(ripple) => ripple.to_substance(),
2265            DirectedWave::Signal(signal) => signal.to_substance(),
2266        }
2267    }
2268
2269    fn to_substance_ref(&self) -> Result<&S, SpaceErr> {
2270        match self {
2271            DirectedWave::Ping(ping) => ping.to_substance_ref(),
2272            DirectedWave::Ripple(ripple) => ripple.to_substance_ref(),
2273            DirectedWave::Signal(signal) => signal.to_substance_ref(),
2274        }
2275    }
2276}
2277
2278impl DirectedWave {
2279    pub fn to_ultra(self) -> UltraWave {
2280        match self {
2281            DirectedWave::Ping(ping) => UltraWave::Ping(ping),
2282            DirectedWave::Ripple(ripple) => UltraWave::Ripple(ripple),
2283            DirectedWave::Signal(signal) => UltraWave::Signal(signal),
2284        }
2285    }
2286}
2287
2288#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
2289pub enum ReflectedWave {
2290    Pong(Wave<Pong>),
2291    Echo(Wave<Echo>),
2292}
2293
2294impl Trackable for ReflectedWave {
2295    fn track_id(&self) -> String {
2296        self.id().to_string()
2297    }
2298
2299    fn track_method(&self) -> String {
2300        self.core().status.to_string()
2301    }
2302
2303    fn track_payload(&self) -> String {
2304        self.core().body.kind().to_string()
2305    }
2306
2307    fn track_from(&self) -> String {
2308        self.from().to_string()
2309    }
2310
2311    fn track_to(&self) -> String {
2312        self.to().to_string()
2313    }
2314
2315    fn track(&self) -> bool {
2316        match self {
2317            ReflectedWave::Pong(pong) => pong.track,
2318            ReflectedWave::Echo(echo) => echo.track,
2319        }
2320    }
2321}
2322
2323impl<S> ToSubstance<S> for ReflectedWave
2324where
2325    Substance: ToSubstance<S>,
2326{
2327    fn to_substance(self) -> Result<S, SpaceErr> {
2328        match self {
2329            ReflectedWave::Pong(pong) => pong.to_substance(),
2330            ReflectedWave::Echo(echo) => echo.to_substance(),
2331        }
2332    }
2333
2334    fn to_substance_ref(&self) -> Result<&S, SpaceErr> {
2335        match self {
2336            ReflectedWave::Pong(pong) => pong.to_substance_ref(),
2337            ReflectedWave::Echo(echo) => echo.to_substance_ref(),
2338        }
2339    }
2340}
2341
2342pub trait ToReflected {
2343    fn to_reflected(self) -> ReflectedWave;
2344    fn from_reflected(reflected: ReflectedWave) -> Result<Self, SpaceErr>
2345    where
2346        Self: Sized;
2347}
2348
2349impl ReflectedWave {
2350    pub fn from(&self) -> &Surface {
2351        match self {
2352            ReflectedWave::Pong(pong) => &pong.from,
2353            ReflectedWave::Echo(echo) => &echo.from,
2354        }
2355    }
2356
2357    pub fn to(&self) -> &Surface {
2358        match self {
2359            ReflectedWave::Pong(pong) => &pong.to,
2360            ReflectedWave::Echo(echo) => &echo.to,
2361        }
2362    }
2363
2364    pub fn id(&self) -> &WaveId {
2365        match self {
2366            ReflectedWave::Pong(pong) => &pong.id,
2367            ReflectedWave::Echo(echo) => &echo.id,
2368        }
2369    }
2370
2371    pub fn to_ultra(self) -> UltraWave {
2372        match self {
2373            ReflectedWave::Pong(pong) => UltraWave::Pong(pong),
2374            ReflectedWave::Echo(echo) => UltraWave::Echo(echo),
2375        }
2376    }
2377
2378    pub fn reflection_of(&self) -> &WaveId {
2379        match self {
2380            ReflectedWave::Pong(pong) => &pong.reflection_of,
2381            ReflectedWave::Echo(echo) => &echo.reflection_of,
2382        }
2383    }
2384
2385    pub fn core(&self) -> &ReflectedCore {
2386        match self {
2387            ReflectedWave::Pong(pong) => &pong.core,
2388            ReflectedWave::Echo(echo) => &echo.core,
2389        }
2390    }
2391
2392    pub fn to_echo(self) -> Result<Wave<Echo>, SpaceErr> {
2393        match self {
2394            ReflectedWave::Echo(echo) => Ok(echo),
2395            _ => Err(SpaceErr::bad_request("expected Wave to be an Echo")),
2396        }
2397    }
2398
2399    pub fn to_pong(self) -> Result<Wave<Pong>, SpaceErr> {
2400        match self {
2401            ReflectedWave::Pong(pong) => Ok(pong),
2402            _ => Err(SpaceErr::bad_request("expecrted wave to be a Pong")),
2403        }
2404    }
2405}
2406
2407impl ReflectedWave {
2408    pub fn is_success(&self) -> bool {
2409        match self {
2410            ReflectedWave::Pong(pong) => return pong.core.status.is_success(),
2411            ReflectedWave::Echo(echo) => return echo.core.status.is_success(),
2412        }
2413    }
2414
2415    pub fn success_or(&self) -> Result<(), SpaceErr> {
2416        if self.is_success() {
2417            Ok(())
2418        } else {
2419            match self {
2420                ReflectedWave::Pong(pong) => Err(SpaceErr::Status {
2421                    status: pong.core.status.as_u16(),
2422                    message: "error".to_string(),
2423                }),
2424                ReflectedWave::Echo(echo) => Err(SpaceErr::Status {
2425                    status: echo.core.status.as_u16(),
2426                    message: "error".to_string(),
2427                }),
2428            }
2429        }
2430    }
2431}
2432
2433#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
2434pub enum Recipients {
2435    Single(Surface),
2436    Multi(Vec<Surface>),
2437    Watchers(Watch),
2438    Stars,
2439}
2440
2441impl ToString for Recipients {
2442    fn to_string(&self) -> String {
2443        match self {
2444            Recipients::Single(surface) => surface.to_string(),
2445            Recipients::Multi(_) => "Multi".to_string(),
2446            Recipients::Watchers(_) => "Watchers".to_string(),
2447            Recipients::Stars => "Stars".to_string(),
2448        }
2449    }
2450}
2451
2452impl ToRecipients for Recipients {
2453    fn to_recipients(self) -> Recipients {
2454        self
2455    }
2456}
2457
2458impl Recipients {
2459    pub fn to_single(self) -> Result<Surface, SpaceErr> {
2460        match self {
2461            Recipients::Single(surface) => Ok(surface),
2462            _ => Err(SpaceErr::server_error(
2463                "cannot convert a multiple recipient into a single",
2464            )),
2465        }
2466    }
2467    pub fn is_match(&self, point: &Point) -> bool {
2468        match self {
2469            Recipients::Single(surface) => surface.point == *point,
2470            Recipients::Multi(ports) => {
2471                for port in ports {
2472                    if port.point == *point {
2473                        return true;
2474                    }
2475                }
2476                false
2477            }
2478            Recipients::Watchers(_) => false,
2479            Recipients::Stars => {
2480                if let RouteSeg::Star(_) = point.route {
2481                    if point.segments.len() == 1
2482                        && *point.segments.first().unwrap() == PointSeg::Space("star".to_string())
2483                    {
2484                        true
2485                    } else {
2486                        false
2487                    }
2488                } else {
2489                    false
2490                }
2491            }
2492        }
2493    }
2494
2495    pub fn split(map: HashMap<Point, Vec<Surface>>) -> HashMap<Point, Recipients> {
2496        let mut rtn = HashMap::new();
2497        for (point, value) in map {
2498            rtn.insert(point, Recipients::Multi(value));
2499        }
2500        rtn
2501    }
2502}
2503
2504impl ToRecipients for &Recipients {
2505    fn to_recipients(self) -> Recipients {
2506        self.clone()
2507    }
2508}
2509
2510pub trait ToRecipients {
2511    fn to_recipients(self) -> Recipients;
2512}
2513
2514impl Recipients {
2515    pub fn select_ports(&self, point: &Point) -> Vec<&Surface> {
2516        let mut rtn = vec![];
2517        match self {
2518            Recipients::Single(surface) => {
2519                if surface.point == *point {
2520                    rtn.push(surface);
2521                }
2522            }
2523            Recipients::Multi(surfaces) => {
2524                for surface in surfaces {
2525                    if surface.point == *point {
2526                        rtn.push(surface);
2527                    }
2528                }
2529            }
2530            Recipients::Watchers(_) => {}
2531            Recipients::Stars => {}
2532        }
2533        rtn
2534    }
2535
2536    pub fn is_single(&self) -> bool {
2537        match self {
2538            Recipients::Single(_) => true,
2539            Recipients::Multi(_) => false,
2540            Recipients::Watchers(_) => false,
2541            Recipients::Stars => false,
2542        }
2543    }
2544
2545    pub fn is_multi(&self) -> bool {
2546        match self {
2547            Recipients::Single(_) => false,
2548            Recipients::Multi(_) => true,
2549            Recipients::Watchers(_) => false,
2550            Recipients::Stars => false,
2551        }
2552    }
2553
2554    pub fn is_stars(&self) -> bool {
2555        match self {
2556            Recipients::Single(_) => false,
2557            Recipients::Multi(_) => false,
2558            Recipients::Watchers(_) => false,
2559            Recipients::Stars => true,
2560        }
2561    }
2562
2563    pub fn is_watch(&self) -> bool {
2564        match self {
2565            Recipients::Single(_) => false,
2566            Recipients::Multi(_) => false,
2567            Recipients::Watchers(_) => true,
2568            Recipients::Stars => false,
2569        }
2570    }
2571
2572    pub fn unwrap_single(self) -> Surface {
2573        self.single_or().expect("single")
2574    }
2575
2576    pub fn single_or(self) -> Result<Surface, SpaceErr> {
2577        if let Recipients::Single(rtn) = self {
2578            Ok(rtn)
2579        } else {
2580            Err("not a single".into())
2581        }
2582    }
2583}
2584
2585pub type IpAddr = String;
2586
2587#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
2588pub enum Origin {
2589    Ip(IpAddr),
2590    Point(Point),
2591}
2592
2593#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
2594pub struct Crypt<S> {
2595    pub payload: S,
2596}
2597
2598#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
2599pub struct SessionId {
2600    pub origin: Crypt<Origin>,
2601    pub uuid: Uuid,
2602}
2603
2604#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
2605pub struct Wave<V> {
2606    pub id: WaveId,
2607    pub session: Option<SessionId>,
2608    pub variant: V,
2609    pub agent: Agent,
2610    pub handling: Handling,
2611    pub scope: Scope,
2612    pub from: Surface,
2613    pub via: Option<Surface>,
2614    pub hops: u16,
2615    pub track: bool,
2616}
2617
2618impl<S, V> ToSubstance<S> for Wave<V>
2619where
2620    V: ToSubstance<S>,
2621{
2622    fn to_substance(self) -> Result<S, SpaceErr> {
2623        self.variant.to_substance()
2624    }
2625
2626    fn to_substance_ref(&self) -> Result<&S, SpaceErr> {
2627        self.variant.to_substance_ref()
2628    }
2629}
2630
2631impl<V> Wave<V> {
2632    pub fn inc_hops(&mut self) {
2633        self.hops = self.hops + 1;
2634    }
2635}
2636
2637impl Wave<Ripple> {
2638    pub fn to_ultra(self) -> UltraWave {
2639        UltraWave::Ripple(self)
2640    }
2641
2642    pub fn to_directed(self) -> DirectedWave {
2643        DirectedWave::Ripple(self)
2644    }
2645
2646    pub fn with_core(mut self, core: DirectedCore) -> Self {
2647        self.variant.core = core;
2648        self
2649    }
2650}
2651
2652impl<T> Wave<RippleDef<T>>
2653where
2654    T: ToRecipients + Clone,
2655{
2656    pub fn err(&self, err: SpaceErr, responder: Surface) -> Wave<Echo> {
2657        Wave::new(
2658            Echo::new(
2659                self.variant.err(err),
2660                self.from.clone(),
2661                self.to.clone().to_recipients(),
2662                self.id.clone(),
2663            ),
2664            responder,
2665        )
2666    }
2667}
2668
2669impl Trackable for Wave<Signal> {
2670    fn track_id(&self) -> String {
2671        self.id.to_short_string()
2672    }
2673
2674    fn track_method(&self) -> String {
2675        self.method.to_deep_string()
2676    }
2677
2678    fn track_payload(&self) -> String {
2679        self.core.body.kind().to_string()
2680    }
2681
2682    fn track_from(&self) -> String {
2683        self.from.to_string()
2684    }
2685
2686    fn track_to(&self) -> String {
2687        self.to.to_string()
2688    }
2689
2690    fn track(&self) -> bool {
2691        self.track
2692    }
2693
2694    fn track_payload_fmt(&self) -> String {
2695        match &self.core.body {
2696            Substance::UltraWave(wave) => {
2697                format!("UltraWave({})", wave.track_key_fmt())
2698            }
2699            _ => self.track_payload(),
2700        }
2701    }
2702}
2703
2704impl Wave<Signal> {
2705    pub fn to_ultra(self) -> UltraWave {
2706        UltraWave::Signal(self)
2707    }
2708
2709    pub fn to_directed(self) -> DirectedWave {
2710        DirectedWave::Signal(self)
2711    }
2712
2713    pub fn with_core(mut self, core: DirectedCore) -> Self {
2714        self.variant.core = core;
2715        self
2716    }
2717
2718    pub fn wrap_in_hop(self, from: Surface, to: Surface) -> DirectedProto {
2719        let mut signal = DirectedProto::signal();
2720        signal.from(from);
2721        signal.agent(self.agent.clone());
2722        signal.handling(self.handling.clone());
2723        signal.method(HypMethod::Hop);
2724        signal.track = self.track;
2725        signal.body(Substance::UltraWave(Box::new(self.to_ultra())));
2726        signal.to(to);
2727        signal
2728    }
2729
2730    pub fn unwrap_from_hop(self) -> Result<Wave<Signal>, SpaceErr> {
2731        if self.method != Method::Hyp(HypMethod::Hop) {
2732            return Err(SpaceErr::server_error(
2733                "expected signal wave to have method Hop",
2734            ));
2735        }
2736        if let Substance::UltraWave(wave) = &self.body {
2737            Ok((*wave.clone()).to_signal()?)
2738        } else {
2739            Err(SpaceErr::server_error(
2740                "expected body substance to be of type UltraWave for a transport signal",
2741            ))
2742        }
2743    }
2744
2745    pub fn unwrap_from_transport(self) -> Result<UltraWave, SpaceErr> {
2746        if self.method != Method::Hyp(HypMethod::Transport) {
2747            return Err(SpaceErr::server_error(
2748                "expected signal wave to have method Transport",
2749            ));
2750        }
2751        if let Substance::UltraWave(wave) = &self.body {
2752            Ok(*wave.clone())
2753        } else {
2754            Err(SpaceErr::server_error(
2755                "expected body substance to be of type UltraWave for a transport signal",
2756            ))
2757        }
2758    }
2759
2760    pub fn to_singular_directed(self) -> SingularDirectedWave {
2761        SingularDirectedWave::Signal(self)
2762    }
2763}
2764
2765impl<S> ToSubstance<S> for Signal
2766where
2767    Substance: ToSubstance<S>,
2768{
2769    fn to_substance(self) -> Result<S, SpaceErr> {
2770        self.core.to_substance()
2771    }
2772
2773    fn to_substance_ref(&self) -> Result<&S, SpaceErr> {
2774        self.core.to_substance_ref()
2775    }
2776}
2777
2778impl Trackable for Wave<Ping> {
2779    fn track_id(&self) -> String {
2780        self.id.to_short_string()
2781    }
2782
2783    fn track_method(&self) -> String {
2784        self.method.to_deep_string()
2785    }
2786
2787    fn track_payload(&self) -> String {
2788        self.core.body.kind().to_string()
2789    }
2790
2791    fn track_from(&self) -> String {
2792        self.from.to_string()
2793    }
2794
2795    fn track_to(&self) -> String {
2796        self.to.to_string()
2797    }
2798
2799    fn track(&self) -> bool {
2800        self.track
2801    }
2802
2803    fn track_payload_fmt(&self) -> String {
2804        match &self.core.body {
2805            Substance::UltraWave(wave) => {
2806                format!("UltraWave({})", wave.track_key_fmt())
2807            }
2808            _ => self.track_payload(),
2809        }
2810    }
2811}
2812
2813impl Wave<Ping> {
2814    pub fn to_ultra(self) -> UltraWave {
2815        UltraWave::Ping(self)
2816    }
2817
2818    pub fn to_directed(self) -> DirectedWave {
2819        DirectedWave::Ping(self)
2820    }
2821
2822    pub fn err(&self, err: SpaceErr, responder: Surface) -> Wave<Pong> {
2823        Wave::new(
2824            Pong::new(
2825                self.variant.err(err),
2826                self.from.clone(),
2827                self.to.clone().to_recipients(),
2828                self.id.clone(),
2829            ),
2830            responder,
2831        )
2832    }
2833
2834    pub fn bounce_backs(&self) -> BounceBacks {
2835        BounceBacks::Single
2836    }
2837}
2838
2839impl Wave<Pong> {
2840    pub fn to_ultra(self) -> UltraWave {
2841        UltraWave::Pong(self)
2842    }
2843
2844    pub fn to_reflected(self) -> ReflectedWave {
2845        ReflectedWave::Pong(self)
2846    }
2847}
2848
2849impl ToReflected for Wave<Pong> {
2850    fn to_reflected(self) -> ReflectedWave {
2851        ReflectedWave::Pong(self)
2852    }
2853
2854    fn from_reflected(reflected: ReflectedWave) -> Result<Self, SpaceErr> {
2855        match reflected {
2856            ReflectedWave::Pong(pong) => Ok(pong),
2857            _ => Err(SpaceErr::bad_request("expected wave to be a Pong")),
2858        }
2859    }
2860}
2861
2862impl ToReflected for Wave<Echo> {
2863    fn to_reflected(self) -> ReflectedWave {
2864        ReflectedWave::Echo(self)
2865    }
2866
2867    fn from_reflected(reflected: ReflectedWave) -> Result<Self, SpaceErr> {
2868        match reflected {
2869            ReflectedWave::Echo(echo) => Ok(echo),
2870            _ => Err(SpaceErr::bad_request("expected Wave to be an Echo")),
2871        }
2872    }
2873}
2874
2875impl Wave<Echo> {
2876    pub fn to_ultra(self) -> UltraWave {
2877        UltraWave::Echo(self)
2878    }
2879
2880    pub fn to_reflected(self) -> ReflectedWave {
2881        ReflectedWave::Echo(self)
2882    }
2883}
2884
2885impl TryFrom<ReflectedWave> for Wave<Pong> {
2886    type Error = SpaceErr;
2887
2888    fn try_from(wave: ReflectedWave) -> Result<Self, Self::Error> {
2889        match wave {
2890            ReflectedWave::Pong(pong) => Ok(pong),
2891            _ => Err(SpaceErr::bad_request("Expected Wave to be a Pong")),
2892        }
2893    }
2894}
2895
2896impl<V> Wave<V> {
2897    pub fn new(variant: V, from: Surface) -> Self
2898    where
2899        V: WaveVariant,
2900    {
2901        Self {
2902            id: WaveId::new(variant.kind().clone()),
2903            session: None,
2904            agent: Default::default(),
2905            handling: Default::default(),
2906            scope: Default::default(),
2907            variant,
2908            from,
2909            hops: 0,
2910            track: false,
2911            via: None,
2912        }
2913    }
2914
2915    pub fn replace<V2>(self, variant: V2) -> Wave<V2>
2916    where
2917        V2: WaveVariant,
2918    {
2919        Wave {
2920            id: self.id,
2921            session: self.session,
2922            agent: self.agent,
2923            handling: self.handling,
2924            scope: self.scope,
2925            variant,
2926            from: self.from,
2927            hops: self.hops,
2928            track: false,
2929            via: self.via,
2930        }
2931    }
2932}
2933
2934pub trait WaveVariant {
2935    fn kind(&self) -> WaveKind;
2936}
2937
2938impl WaveVariant for Ping {
2939    fn kind(&self) -> WaveKind {
2940        WaveKind::Ping
2941    }
2942}
2943
2944impl WaveVariant for Pong {
2945    fn kind(&self) -> WaveKind {
2946        WaveKind::Pong
2947    }
2948}
2949
2950impl<T> WaveVariant for RippleDef<T>
2951where
2952    T: ToRecipients + Clone,
2953{
2954    fn kind(&self) -> WaveKind {
2955        WaveKind::Ripple
2956    }
2957}
2958
2959impl WaveVariant for Echo {
2960    fn kind(&self) -> WaveKind {
2961        WaveKind::Echo
2962    }
2963}
2964
2965impl Wave<Ping> {
2966    pub fn pong(&self) -> ReflectedProto {
2967        let mut pong = ReflectedProto::new();
2968        pong.kind(ReflectedKind::Pong);
2969        pong.fill(self);
2970        pong
2971    }
2972}
2973
2974impl<T> Wave<RippleDef<T>>
2975where
2976    T: ToRecipients + Clone,
2977{
2978    pub fn echo(&self) -> ReflectedProto {
2979        let mut echo = ReflectedProto::new();
2980        echo.kind(ReflectedKind::Echo);
2981        echo.fill(self);
2982        echo
2983    }
2984
2985    pub fn bounce_backs(&self) -> BounceBacks {
2986        self.bounce_backs.clone()
2987    }
2988}
2989
2990impl Wave<SingularRipple> {
2991    pub fn to_singular_directed(self) -> SingularDirectedWave {
2992        SingularDirectedWave::Ripple(self)
2993    }
2994}
2995
2996impl DirectedWave {
2997    pub fn reflected_proto(&self) -> BounceProto {
2998        match self {
2999            DirectedWave::Ping(ping) => BounceProto::Reflected(ping.pong()),
3000            DirectedWave::Ripple(ripple) => BounceProto::Reflected(ripple.echo()),
3001            DirectedWave::Signal(_) => BounceProto::Absorbed,
3002        }
3003    }
3004}
3005
3006impl<V> Deref for Wave<V> {
3007    type Target = V;
3008
3009    fn deref(&self) -> &Self::Target {
3010        &self.variant
3011    }
3012}
3013
3014impl<V> DerefMut for Wave<V> {
3015    fn deref_mut(&mut self) -> &mut Self::Target {
3016        &mut self.variant
3017    }
3018}
3019
3020#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
3021pub enum Agent {
3022    Anonymous,
3023    HyperUser,
3024    Point(Point),
3025}
3026
3027impl ToPoint for Agent {
3028    fn to_point(&self) -> Point {
3029        match self {
3030            Agent::Anonymous => ANONYMOUS.clone(),
3031            Agent::HyperUser => HYPERUSER.clone(),
3032            Agent::Point(point) => point.clone(),
3033        }
3034    }
3035}
3036
3037impl Default for Agent {
3038    fn default() -> Self {
3039        Self::Anonymous
3040    }
3041}
3042
3043#[derive(Debug, Clone, Serialize, Deserialize)]
3044pub struct Session {
3045    pub id: Uuid,
3046    pub attributes: HashMap<String, String>,
3047}
3048
3049impl Session {
3050    pub fn new() -> Self {
3051        Self {
3052            id: uuid(),
3053            attributes: HashMap::new(),
3054        }
3055    }
3056    pub fn get_preferred_username(&self) -> Option<String> {
3057        self.attributes
3058            .get(&"preferred_username".to_string())
3059            .cloned()
3060    }
3061}
3062
3063#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
3064pub enum Scope {
3065    Full,
3066    None,
3067    Grants(HashSet<ScopeGrant>),
3068}
3069
3070impl Scope {
3071    pub fn has_grant(&self, grant: &ScopeGrant) -> Result<(), ()> {
3072        match self {
3073            Scope::Full => Ok(()),
3074            Scope::None => Err(()),
3075            Scope::Grants(grants) if grants.contains(grant) => Ok(()),
3076            _ => Err(()),
3077        }
3078    }
3079
3080    pub fn enumerated_grants(&self) -> HashSet<ScopeGrant> {
3081        match self {
3082            Scope::Full => HashSet::new(),
3083            Scope::None => HashSet::new(),
3084            Scope::Grants(grants) => grants.clone(),
3085        }
3086    }
3087}
3088
3089impl From<HashSet<ScopeGrant>> for Scope {
3090    fn from(grants: HashSet<ScopeGrant>) -> Self {
3091        Scope::Grants(grants)
3092    }
3093}
3094
3095impl ops::BitAnd<Scope> for Scope {
3096    type Output = Scope;
3097
3098    fn bitand(self, rhs: Scope) -> Self::Output {
3099        if self == Self::Full && rhs == Self::Full {
3100            Self::Full
3101        } else if self == Self::None || rhs == Self::None {
3102            Self::None
3103        } else {
3104            let mut grants = self.enumerated_grants();
3105            grants.retain(|grant| rhs.has_grant(grant).is_ok());
3106            grants.into()
3107        }
3108    }
3109}
3110
3111impl ops::BitOr<Scope> for Scope {
3112    type Output = Scope;
3113
3114    fn bitor(self, rhs: Scope) -> Self::Output {
3115        if self == Self::Full || rhs == Scope::Full {
3116            Self::Full
3117        } else {
3118            let left = self.enumerated_grants();
3119            let right = rhs.enumerated_grants();
3120            Self::Grants(left.union(&right).cloned().collect())
3121        }
3122    }
3123}
3124
3125impl Scope {
3126    /*
3127    pub fn mask( &self, on: &AddressKindPath ) -> Access {
3128        match self {
3129            Scope::Full => {
3130                access.clone()
3131            }
3132            Scope::None => {
3133                Access::none()
3134            }
3135            Scope::Grants(grants) => {
3136                let mut access  = access.clone();
3137                let mut privileges = EnumeratedPrivileges::none();
3138                let mut permissions = Permissions::full();
3139                for grant in grants {
3140                   if grant.on.matches(on) {
3141                       match &grant.aspect {
3142                           ScopeGrantAspect::Perm(and) => permissions.and(and),
3143                           ScopeGrantAspect::Priv(and) =>  privileges.insert(and.clone())
3144                       }
3145                   }
3146               }
3147            }
3148        }
3149    }
3150
3151     */
3152}
3153
3154impl Default for Scope {
3155    fn default() -> Self {
3156        Self::None
3157    }
3158}
3159
3160#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
3161pub struct ScopeGrant {
3162    pub on: Selector,
3163    pub kind: ScopeGrantKind,
3164    pub aspect: ScopeGrantAspect,
3165}
3166
3167#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
3168pub enum ScopeGrantKind {
3169    Or,
3170    And,
3171}
3172
3173#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
3174pub enum ScopeGrantAspect {
3175    Perm(Permissions),
3176    Priv(Privilege),
3177}
3178
3179#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
3180pub struct Handling {
3181    pub kind: HandlingKind,
3182    pub priority: Priority,
3183    pub retries: Retries,
3184    pub wait: WaitTime,
3185}
3186
3187#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
3188pub enum HandlingKind {
3189    Durable,   // Mesh will guarantee delivery eventually once Request call has returned
3190    Queued,    // Slower but more reliable delivery, message can be lost if a star crashes, etc
3191    Immediate, // Wave should never touch a filesystem, it will be in memory for its entire journey for immediate processing
3192}
3193
3194impl Default for Handling {
3195    fn default() -> Self {
3196        Self {
3197            kind: HandlingKind::Queued,
3198            priority: Default::default(),
3199            retries: Default::default(),
3200            wait: Default::default(),
3201        }
3202    }
3203}
3204
3205#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
3206pub enum WaitTime {
3207    High,
3208    Med,
3209    Low,
3210}
3211
3212impl Default for WaitTime {
3213    fn default() -> Self {
3214        WaitTime::Low
3215    }
3216}
3217
3218#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
3219pub enum Retries {
3220    None,
3221    Max,
3222    Medium,
3223    Min,
3224}
3225
3226impl Default for Retries {
3227    fn default() -> Self {
3228        Retries::None
3229    }
3230}
3231
3232#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
3233pub enum Priority {
3234    Hyper,
3235    Super,
3236    High,
3237    Med,
3238    Low,
3239}
3240
3241impl Default for Priority {
3242    fn default() -> Self {
3243        Self::Med
3244    }
3245}
3246
3247#[derive(Debug, Clone, Serialize, Deserialize)]
3248pub enum Karma {
3249    Hyper,
3250    Super,
3251    High,
3252    Med,
3253    Low,
3254    None,
3255}
3256
3257impl Default for Karma {
3258    fn default() -> Self {
3259        Self::High
3260    }
3261}
3262
3263#[derive(Debug, Clone, Serialize, Deserialize)]
3264pub enum Urgency {
3265    High,
3266    Low,
3267}
3268
3269pub trait TransportPlanner {
3270    fn dest(&self, surface: Surface) -> Surface;
3271}
3272
3273pub enum Bounce<W> {
3274    Absorbed,
3275    Reflected(W),
3276}
3277
3278impl<W> Bounce<W> {
3279    pub fn to_core_bounce(self) -> CoreBounce
3280    where
3281        W: TryInto<ReflectedCore, Error = SpaceErr>,
3282    {
3283        match self {
3284            Bounce::Absorbed => Bounce::Absorbed,
3285            Bounce::Reflected(reflected) => match reflected.try_into() {
3286                Ok(reflected) => CoreBounce::Reflected(reflected),
3287                Err(err) => CoreBounce::Reflected(err.as_reflected_core()),
3288            },
3289        }
3290    }
3291}
3292
3293impl Into<CoreBounce> for Bounce<ReflectedWave> {
3294    fn into(self) -> CoreBounce {
3295        match self {
3296            Bounce::Absorbed => CoreBounce::Absorbed,
3297            Bounce::Reflected(reflected) => CoreBounce::Reflected(reflected.core().clone()),
3298        }
3299    }
3300}
3301
3302pub enum BounceProto {
3303    Absorbed,
3304    Reflected(ReflectedProto),
3305}
3306
3307#[derive(Debug, Clone, Serialize, Deserialize)]
3308pub enum ReflectedAggregate {
3309    None,
3310    Single(ReflectedWave),
3311    Multi(Vec<ReflectedWave>),
3312}
3313
3314pub trait FromReflectedAggregate {
3315    fn from_reflected_aggregate(agg: ReflectedAggregate) -> Result<Self, SpaceErr>
3316    where
3317        Self: Sized;
3318}
3319
3320impl TryInto<Wave<Pong>> for ReflectedAggregate {
3321    type Error = SpaceErr;
3322    fn try_into(self) -> Result<Wave<Pong>, Self::Error> {
3323        match self {
3324            Self::Single(reflected) => match reflected {
3325                ReflectedWave::Pong(pong) => Ok(pong),
3326                _ => Err(SpaceErr::bad_request(
3327                    "Expected ReflectedAggregate to be for a Pong",
3328                )),
3329            },
3330            _ => Err(SpaceErr::bad_request(
3331                "Expected ReflectedAggregate to be a Single",
3332            )),
3333        }
3334    }
3335}
3336
3337impl TryInto<Vec<Wave<Echo>>> for ReflectedAggregate {
3338    type Error = SpaceErr;
3339    fn try_into(self) -> Result<Vec<Wave<Echo>>, Self::Error> {
3340        match self {
3341            Self::Single(reflected) => match reflected {
3342                ReflectedWave::Echo(echo) => Ok(vec![echo]),
3343                _ => Err(SpaceErr::bad_request(
3344                    "Expected Reflected to be a Single Echo",
3345                )),
3346            },
3347            ReflectedAggregate::None => Ok(vec![]),
3348            ReflectedAggregate::Multi(waves) => {
3349                let mut echoes = vec![];
3350                for w in waves {
3351                    echoes.push(w.to_echo()?);
3352                }
3353                Ok(echoes)
3354            }
3355        }
3356    }
3357}
3358
3359#[derive(Clone)]
3360pub struct Delivery {
3361    pub to: Surface,
3362    pub wave: DirectedWave,
3363}
3364
3365impl Delivery {
3366    pub fn new(to: Surface, wave: DirectedWave) -> Self {
3367        Self { to, wave }
3368    }
3369}
3370
3371impl Deref for Delivery {
3372    type Target = DirectedWave;
3373
3374    fn deref(&self) -> &Self::Target {
3375        &self.wave
3376    }
3377}
3378
3379#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
3380pub struct HyperWave {
3381    point: Point,
3382    wave: UltraWave,
3383}