cosmic_space/wave/exchange/
synch.rs1use crate::loc::ToPoint;
2use crate::wave::core::cmd::CmdMethod;
3use crate::wave::core::CoreBounce;
4use crate::wave::exchange::{
5 DirectedHandlerShellDef, InCtxDef, ProtoTransmitterBuilderDef, ProtoTransmitterDef,
6 RootInCtxDef, SetStrategy,
7};
8use crate::wave::{
9 Bounce, BounceBacks, DirectedKind, DirectedProto, DirectedWave, Echo, FromReflectedAggregate,
10 Handling, Ping, Pong, RecipientSelector, ReflectedAggregate, ReflectedProto, ReflectedWave,
11 Scope, UltraWave, Wave, WaveKind,
12};
13use crate::{Agent, ReflectedCore, SpaceErr, Substance, Surface, ToSubstance};
14use alloc::borrow::Cow;
15use std::sync::Arc;
16
17pub trait ExchangeRouter: Send + Sync {
18 fn route(&self, wave: UltraWave);
19 fn exchange(&self, direct: DirectedWave) -> Result<ReflectedAggregate, SpaceErr>;
20}
21
22#[derive(Clone)]
23pub struct SyncRouter {
24 pub router: Arc<dyn ExchangeRouter>,
25}
26
27impl SyncRouter {
28 pub fn new(router: Arc<dyn ExchangeRouter>) -> Self {
29 Self { router }
30 }
31}
32
33impl ExchangeRouter for SyncRouter {
34 fn route(&self, wave: UltraWave) {
35 self.router.route(wave)
36 }
37
38 fn exchange(&self, direct: DirectedWave) -> Result<ReflectedAggregate, SpaceErr> {
39 self.router.exchange(direct)
40 }
41}
42
43pub type ProtoTransmitter = ProtoTransmitterDef<SyncRouter, ()>;
44
45impl ProtoTransmitter {
46 pub fn new(router: Arc<dyn ExchangeRouter>) -> ProtoTransmitter {
47 let router = SyncRouter::new(router);
48 Self {
49 from: SetStrategy::None,
50 to: SetStrategy::None,
51 via: SetStrategy::None,
52 agent: SetStrategy::Fill(Agent::Anonymous),
53 scope: SetStrategy::Fill(Scope::None),
54 handling: SetStrategy::Fill(Handling::default()),
55 method: SetStrategy::None,
56 router,
57 exchanger: (),
58 }
59 }
60
61 pub fn direct<D, W>(&self, wave: D) -> Result<W, SpaceErr>
62 where
63 W: FromReflectedAggregate,
64 D: Into<DirectedProto>,
65 {
66 let mut wave: DirectedProto = wave.into();
67
68 self.prep_direct(&mut wave);
69
70 let directed = wave.build()?;
71
72 println!("DIRECTE!");
73 match directed.bounce_backs() {
74 BounceBacks::None => {
75 self.router.route(directed.to_ultra());
76 FromReflectedAggregate::from_reflected_aggregate(ReflectedAggregate::None)
77 }
78 _ => FromReflectedAggregate::from_reflected_aggregate(self.router.exchange(directed)?),
79 }
80 }
81
82 pub fn ping<D>(&self, ping: D) -> Result<Wave<Pong>, SpaceErr>
83 where
84 D: Into<DirectedProto>,
85 {
86 println!("PING!");
87 let mut ping: DirectedProto = ping.into();
88 ping.bounce_backs = Some(BounceBacks::Single);
89 if let Some(DirectedKind::Ping) = ping.kind {
90 self.direct(ping)
91 } else {
92 Err(SpaceErr::server_error("expected DirectedKind::Ping"))
93 }
94 }
95
96 pub fn ripple<D>(&self, ripple: D) -> Result<Vec<Wave<Echo>>, SpaceErr>
97 where
98 D: Into<DirectedProto>,
99 {
100 let mut ripple: DirectedProto = ripple.into();
101 if let Some(DirectedKind::Ripple) = ripple.kind {
102 self.direct(ripple)
103 } else {
104 Err(SpaceErr::server_error("expected DirectedKind::Ping"))
105 }
106 }
107
108 pub fn signal<D>(&self, signal: D) -> Result<(), SpaceErr>
109 where
110 D: Into<DirectedProto>,
111 {
112 let mut signal: DirectedProto = signal.into();
113 if let Some(DirectedKind::Signal) = signal.kind {
114 self.direct(signal)
115 } else {
116 Err(SpaceErr::server_error("expected DirectedKind::Ping"))
117 }
118 }
119
120 pub fn bounce_from(&self, to: &Surface, from: &Surface) -> bool {
121 let mut directed = DirectedProto::ping();
122 directed.from(from.clone());
123 directed.to(to.clone());
124 directed.method(CmdMethod::Bounce);
125 match self.ping(directed) {
126 Ok(pong) => pong.is_ok(),
127 Err(_) => false,
128 }
129 }
130
131 pub fn bounce(&self, to: &Surface) -> bool {
132 let mut directed = DirectedProto::ping();
133 directed.to(to.clone());
134 directed.method(CmdMethod::Bounce);
135 match self.ping(directed) {
136 Ok(pong) => pong.is_ok(),
137 Err(_) => false,
138 }
139 }
140
141 pub fn route(&self, wave: UltraWave) {
142 self.router.route(wave)
143 }
144
145 pub fn reflect<W>(&self, wave: W) -> Result<(), SpaceErr>
146 where
147 W: Into<ReflectedProto>,
148 {
149 let mut wave: ReflectedProto = wave.into();
150
151 self.prep_reflect(&mut wave);
152
153 let wave = wave.build()?;
154 let wave = wave.to_ultra();
155 self.router.route(wave);
156
157 Ok(())
158 }
159}
160
161pub type ProtoTransmitterBuilder = ProtoTransmitterBuilderDef<SyncRouter, ()>;
162
163impl ProtoTransmitterBuilder {
164 pub fn new(router: Arc<dyn ExchangeRouter>) -> ProtoTransmitterBuilder {
165 let router = SyncRouter::new(router);
166 Self {
167 from: SetStrategy::None,
168 to: SetStrategy::None,
169 via: SetStrategy::None,
170 agent: SetStrategy::Fill(Agent::Anonymous),
171 scope: SetStrategy::Fill(Scope::None),
172 handling: SetStrategy::Fill(Handling::default()),
173 method: SetStrategy::None,
174 router,
175 exchanger: (),
176 }
177 }
178}
179
180pub type RootInCtx = RootInCtxDef<ProtoTransmitter>;
181
182pub type InCtx<'a, I> = InCtxDef<'a, I, ProtoTransmitter>;
183
184impl<'a, I> InCtx<'a, I> {
185 pub fn push_from(self, from: Surface) -> InCtx<'a, I> {
186 let mut transmitter = self.transmitter.clone();
187 transmitter.to_mut().from = SetStrategy::Override(from);
188 InCtx {
189 root: self.root,
190 input: self.input,
191 logger: self.logger.clone(),
192 transmitter,
193 }
194 }
195}
196
197pub trait DirectedHandlerSelector {
198 fn select<'a>(&self, select: &'a RecipientSelector<'a>) -> Result<&dyn DirectedHandler, ()>;
199}
200
201pub trait DirectedHandler: Send + Sync {
202 fn handle(&self, ctx: RootInCtx) -> CoreBounce;
203
204 fn bounce(&self, ctx: RootInCtx) -> CoreBounce {
205 CoreBounce::Reflected(ReflectedCore::ok())
206 }
207}
208
209pub struct DirectedHandlerProxy {
210 proxy: Box<dyn DirectedHandler>,
211}
212
213impl DirectedHandlerProxy {
214 pub fn new<D>(handler: D) -> Self
215 where
216 D: DirectedHandler + 'static + Sized,
217 {
218 Self {
219 proxy: Box::new(handler),
220 }
221 }
222
223 pub fn boxed<D>(handler: Box<D>) -> Self
224 where
225 D: DirectedHandler + 'static + Sized,
226 {
227 Self { proxy: handler }
228 }
229}
230
231impl DirectedHandler for DirectedHandlerProxy {
232 fn handle(&self, ctx: RootInCtx) -> CoreBounce {
233 self.proxy.handle(ctx)
234 }
235}
236
237pub type DirectedHandlerShell =
238 DirectedHandlerShellDef<Box<dyn DirectedHandler>, ProtoTransmitterBuilder>;
239
240impl DirectedHandlerShell {
241 pub fn handle(&self, wave: DirectedWave) -> Bounce<ReflectedWave> {
242 let logger = self
243 .logger
244 .point(self.surface.clone().to_point())
245 .spanner(&wave);
246 let mut transmitter = self.builder.clone().build();
247 let reflection = wave.reflection();
248 let ctx = RootInCtx::new(wave, self.surface.clone(), logger, transmitter.clone());
249 match self.handler.handle(ctx) {
250 CoreBounce::Absorbed => Bounce::Absorbed,
251 CoreBounce::Reflected(reflected) => {
252 let wave = reflection.unwrap().make(reflected, self.surface.clone());
253 Bounce::Reflected(wave)
254 }
255 }
256 }
257}
258
259impl RootInCtx {
260 pub fn push<'a, I>(&self) -> Result<InCtx<I>, SpaceErr>
261 where
262 Substance: ToSubstance<I>,
263 {
264 let input = match self.wave.to_substance_ref() {
265 Ok(input) => input,
266 Err(err) => return Err(err.into()),
267 };
268 Ok(InCtx {
269 root: self,
270 input,
271 logger: self.logger.clone(),
272 transmitter: Cow::Borrowed(&self.transmitter),
273 })
274 }
275}