crux_core/middleware/
bridge.rs1use std::{marker::PhantomData, sync::Arc};
2
3use serde::{Deserialize, Serialize};
4
5use super::Layer;
6use crate::{
7 EffectFFI,
8 bridge::{BridgeError, EffectId, FfiFormat, ResolveRegistry},
9};
10
11#[doc(hidden)]
12pub type EffectCallback<Format> =
13 dyn Fn(Result<Vec<u8>, BridgeError<Format>>) + Send + Sync + 'static;
14
15pub struct Bridge<Next, Format>
17where
18 Next: Layer,
19 Format: FfiFormat,
20{
21 next: Next,
22 effect_callback: Arc<EffectCallback<Format>>,
23 registry: Arc<ResolveRegistry<Format>>,
24 format: PhantomData<Format>,
25}
26
27impl<Next, Format> Bridge<Next, Format>
28where
29 Next: Layer,
30 Next::Event: for<'a> Deserialize<'a>,
31 Next::Effect: EffectFFI,
32 Format: FfiFormat,
33{
34 pub fn new<F>(next: Next, effect_callback: F) -> Self
36 where
37 F: Fn(Result<Vec<u8>, BridgeError<Format>>) + Send + Sync + 'static,
38 {
39 Self {
40 next,
41 effect_callback: Arc::new(effect_callback),
42 registry: Arc::new(ResolveRegistry::default()),
43 format: PhantomData,
44 }
45 }
46
47 pub fn update(
53 &self,
54 event_bytes: &[u8],
55 requests_out: &mut Vec<u8>,
56 ) -> Result<(), BridgeError<Format>> {
57 self.process(None, event_bytes, requests_out)
58 }
59
60 pub fn resolve(
66 &self,
67 id: EffectId,
68 output: &[u8],
69 requests_out: &mut Vec<u8>,
70 ) -> Result<(), BridgeError<Format>> {
71 self.process(Some(id), output, requests_out)
72 }
73
74 fn process(
75 &self,
76 id: Option<EffectId>,
77 event_or_output: &[u8],
78 requests_out: &mut Vec<u8>,
79 ) -> Result<(), BridgeError<Format>> {
80 let effect_callback = {
81 let shell_callback = self.effect_callback.clone();
82 let registry = self.registry.clone();
83
84 move |effects: Vec<Next::Effect>| {
85 let requests: Vec<_> = effects
86 .into_iter()
87 .map(|eff| registry.register(eff))
88 .collect();
89 let mut requests_bytes = vec![];
90
91 let result = {
92 Format::serialize(&mut requests_bytes, &requests)
93 .map_err(BridgeError::SerializeRequests)
94 };
95
96 shell_callback(result.map(|()| requests_bytes));
97 }
98 };
99
100 let effects = match id {
101 None => {
102 let shell_event =
103 Format::deserialize(event_or_output).map_err(BridgeError::DeserializeEvent)?;
104
105 self.next.update(shell_event, effect_callback)
106 }
107 Some(id) => {
108 self.registry.resume(id, event_or_output)?;
109
110 self.next.process_tasks(effect_callback)
111 }
112 };
113
114 let requests: Vec<_> = effects
115 .into_iter()
116 .map(|eff| self.registry.register(eff))
117 .collect();
118
119 Format::serialize(requests_out, &requests).map_err(BridgeError::SerializeRequests)?;
120
121 Ok(())
122 }
123
124 pub fn view(&self, view_out: &mut Vec<u8>) -> Result<(), BridgeError<Format>>
130 where
131 Next::ViewModel: Serialize,
132 {
133 Format::serialize(view_out, &self.next.view()).map_err(BridgeError::SerializeView)
134 }
135}