1mod formats;
2mod registry;
3mod request_serde;
4
5use facet::Facet;
6use serde::{Deserialize, Serialize};
7use std::fmt::Debug;
8use thiserror::Error;
9
10use crate::{App, Core, core::ResolveError};
11pub use formats::{BincodeFfiFormat, JsonFfiFormat};
12pub use registry::EffectId;
13pub(crate) use registry::ResolveRegistry;
14#[doc(hidden)]
16pub use request_serde::ResolveSerialized;
17
18pub trait FfiFormat: Debug + 'static {
24 type Error: std::error::Error;
25
26 fn serialize<T: Serialize>(buffer: &mut Vec<u8>, value: &T) -> Result<(), Self::Error>;
32
33 fn deserialize<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, Self::Error>;
39}
40
41#[derive(Facet, Debug, Serialize, Deserialize)]
47pub struct Request<Eff>
48where
49 Eff: Serialize,
50{
51 pub id: EffectId,
52 pub effect: Eff,
53}
54pub struct Bridge<A, F = BincodeFfiFormat>
59where
60 A: App,
61 F: FfiFormat,
62{
63 core: Core<A>,
64 registry: ResolveRegistry<F>,
65}
66
67#[derive(Debug, Error)]
68pub enum BridgeError<F: FfiFormat = BincodeFfiFormat> {
69 #[error("could not deserialize event: {0}")]
70 DeserializeEvent(F::Error),
71 #[error("could not deserialize provided effect output: {0}")]
72 DeserializeOutput(F::Error),
73 #[error("could not process response: {0}")]
74 ProcessResponse(#[from] ResolveError),
75 #[error("could not serialize effect requests: {0}")]
76 SerializeRequests(F::Error),
77 #[error("could not serialize view model: {0}")]
78 SerializeView(F::Error),
79}
80
81impl<A, Format> Bridge<A, Format>
82where
83 A: App,
84 Format: FfiFormat,
85{
86 pub fn new(core: Core<A>) -> Self {
88 Self {
89 core,
90 registry: ResolveRegistry::default(),
91 }
92 }
93
94 #[deprecated(
103 since = "0.17.0",
104 note = "Bridge API returning vectors has been deprecated. Please use the 'update' method."
105 )]
106 pub fn process_event(&self, event: &[u8]) -> Result<Vec<u8>, BridgeError<Format>>
107 where
108 A::Event: for<'a> Deserialize<'a>,
109 A::Effect: crate::core::EffectFFI,
110 {
111 let mut return_buffer = vec![];
112
113 self.update(event, &mut return_buffer)?;
114
115 Ok(return_buffer)
116 }
117
118 pub fn update<'a>(
127 &self,
128 event: &'a [u8],
129 requests_out: &mut Vec<u8>,
130 ) -> Result<(), BridgeError<Format>>
131 where
132 A::Event: Deserialize<'a>,
133 A::Effect: crate::core::EffectFFI,
134 {
135 self.process(None, event, requests_out)
136 }
137
138 #[deprecated(
152 since = "0.17.0",
153 note = "Bridge API returning vectors has been deprecated. Please use the 'resolve' method."
154 )]
155 pub fn handle_response(&self, id: u32, output: &[u8]) -> Result<Vec<u8>, BridgeError<Format>>
156 where
158 A::Event: for<'a> Deserialize<'a>,
159 A::Effect: crate::core::EffectFFI,
160 {
161 let mut return_buffer = vec![];
162
163 self.resolve(EffectId(id), output, &mut return_buffer)?;
164
165 Ok(return_buffer)
166 }
167
168 pub fn resolve<'a>(
180 &self,
181 id: EffectId,
182 response: &'a [u8],
183 requests_out: &mut Vec<u8>,
184 ) -> Result<(), BridgeError<Format>>
185 where
186 A::Event: Deserialize<'a>,
187 A::Effect: crate::core::EffectFFI,
188 {
189 self.process(Some(id), response, requests_out)
190 }
191
192 fn process<'a>(
193 &self,
194 id: Option<EffectId>,
195 data: &'a [u8],
196 requests_out: &mut Vec<u8>,
197 ) -> Result<(), BridgeError<Format>>
198 where
199 A::Event: Deserialize<'a>,
200 A::Effect: crate::core::EffectFFI,
201 {
202 let effects = match id {
203 None => {
204 let shell_event =
205 Format::deserialize(data).map_err(BridgeError::DeserializeEvent)?;
206
207 self.core.process_event(shell_event)
208 }
209 Some(id) => {
210 self.registry.resume(id, data)?;
211
212 self.core.process()
213 }
214 };
215
216 self.process_effects(effects, requests_out)
217 }
218
219 fn process_effects(
220 &self,
221 effects: Vec<A::Effect>,
222 requests_out: &mut Vec<u8>,
223 ) -> Result<(), BridgeError<Format>>
224 where
225 A::Effect: crate::core::EffectFFI,
226 {
227 let requests: Vec<_> = effects
228 .into_iter()
229 .map(|eff| self.registry.register(eff))
230 .collect();
231
232 Format::serialize(requests_out, &requests).map_err(BridgeError::SerializeRequests)?;
233
234 Ok(())
235 }
236
237 pub fn view(&self, view_out: &mut Vec<u8>) -> Result<(), BridgeError<Format>>
243 where
244 A::ViewModel: Serialize,
245 {
246 Format::serialize(view_out, &self.core.view()).map_err(BridgeError::SerializeView)
247 }
248}