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