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}
54#[derive(Facet, Debug, Serialize, Deserialize)]
69#[serde(transparent)]
70pub struct Requests<Eff>(pub Vec<Request<Eff>>)
71where
72 Eff: Serialize;
73
74pub struct Bridge<A, F = BincodeFfiFormat>
77where
78 A: App,
79 F: FfiFormat,
80{
81 core: Core<A>,
82 registry: ResolveRegistry<F>,
83}
84
85#[derive(Debug, Error)]
86pub enum BridgeError<F: FfiFormat = BincodeFfiFormat> {
87 #[error("could not deserialize event: {0}")]
88 DeserializeEvent(F::Error),
89 #[error("could not deserialize provided effect output: {0}")]
90 DeserializeOutput(F::Error),
91 #[error("could not process response: {0}")]
92 ProcessResponse(#[from] ResolveError),
93 #[error("could not serialize effect requests: {0}")]
94 SerializeRequests(F::Error),
95 #[error("could not serialize view model: {0}")]
96 SerializeView(F::Error),
97}
98
99impl<A, Format> Bridge<A, Format>
100where
101 A: App,
102 Format: FfiFormat,
103{
104 pub fn new(core: Core<A>) -> Self {
106 Self {
107 core,
108 registry: ResolveRegistry::default(),
109 }
110 }
111
112 #[deprecated(
121 since = "0.17.0",
122 note = "Bridge API returning vectors has been deprecated. Please use the 'update' method."
123 )]
124 pub fn process_event(&self, event: &[u8]) -> Result<Vec<u8>, BridgeError<Format>>
125 where
126 A::Event: for<'a> Deserialize<'a>,
127 A::Effect: crate::core::EffectFFI,
128 {
129 let mut return_buffer = vec![];
130
131 self.update(event, &mut return_buffer)?;
132
133 Ok(return_buffer)
134 }
135
136 pub fn update<'a>(
145 &self,
146 event: &'a [u8],
147 requests_out: &mut Vec<u8>,
148 ) -> Result<(), BridgeError<Format>>
149 where
150 A::Event: Deserialize<'a>,
151 A::Effect: crate::core::EffectFFI,
152 {
153 self.process(None, event, requests_out)
154 }
155
156 #[deprecated(
170 since = "0.17.0",
171 note = "Bridge API returning vectors has been deprecated. Please use the 'resolve' method."
172 )]
173 pub fn handle_response(&self, id: u32, output: &[u8]) -> Result<Vec<u8>, BridgeError<Format>>
174 where
176 A::Event: for<'a> Deserialize<'a>,
177 A::Effect: crate::core::EffectFFI,
178 {
179 let mut return_buffer = vec![];
180
181 self.resolve(EffectId(id), output, &mut return_buffer)?;
182
183 Ok(return_buffer)
184 }
185
186 pub fn resolve<'a>(
198 &self,
199 id: EffectId,
200 response: &'a [u8],
201 requests_out: &mut Vec<u8>,
202 ) -> Result<(), BridgeError<Format>>
203 where
204 A::Event: Deserialize<'a>,
205 A::Effect: crate::core::EffectFFI,
206 {
207 self.process(Some(id), response, requests_out)
208 }
209
210 fn process<'a>(
211 &self,
212 id: Option<EffectId>,
213 data: &'a [u8],
214 requests_out: &mut Vec<u8>,
215 ) -> Result<(), BridgeError<Format>>
216 where
217 A::Event: Deserialize<'a>,
218 A::Effect: crate::core::EffectFFI,
219 {
220 let effects = match id {
221 None => {
222 let shell_event =
223 Format::deserialize(data).map_err(BridgeError::DeserializeEvent)?;
224
225 self.core.process_event(shell_event)
226 }
227 Some(id) => {
228 self.registry.resume(id, data)?;
229
230 self.core.process()
231 }
232 };
233
234 self.process_effects(effects, requests_out)
235 }
236
237 fn process_effects(
238 &self,
239 effects: Vec<A::Effect>,
240 requests_out: &mut Vec<u8>,
241 ) -> Result<(), BridgeError<Format>>
242 where
243 A::Effect: crate::core::EffectFFI,
244 {
245 let requests: Vec<_> = effects
246 .into_iter()
247 .map(|eff| self.registry.register(eff))
248 .collect();
249
250 Format::serialize(requests_out, &requests).map_err(BridgeError::SerializeRequests)?;
251
252 Ok(())
253 }
254
255 pub fn view(&self, view_out: &mut Vec<u8>) -> Result<(), BridgeError<Format>>
261 where
262 A::ViewModel: Serialize,
263 {
264 Format::serialize(view_out, &self.core.view()).map_err(BridgeError::SerializeView)
265 }
266}