crux_core/bridge/
request_serde.rs1use crate::{
2 Request,
3 capability::Operation,
4 core::{RequestHandle, ResolveError},
5};
6
7use super::{BridgeError, FfiFormat};
8
9type ResolveOnceSerialized<T> = Box<dyn FnOnce(&[u8]) -> Result<(), BridgeError<T>> + Send>;
12type ResolveManySerialized<T> = Box<dyn FnMut(&[u8]) -> Result<(), BridgeError<T>> + Send>;
13
14pub enum ResolveSerialized<T: FfiFormat> {
21 Never,
22 Once(ResolveOnceSerialized<T>),
23 Many(ResolveManySerialized<T>),
24}
25impl<T: FfiFormat> ResolveSerialized<T> {
28 pub(crate) fn resolve(&mut self, response: &[u8]) -> Result<(), BridgeError<T>> {
29 match self {
30 Self::Never => Err(BridgeError::ProcessResponse(ResolveError::Never)),
31 Self::Many(f) => f(response),
32 Self::Once(_) => {
33 let Self::Once(f) = std::mem::replace(self, Self::Never) else {
35 unreachable!("already resolved");
36 };
37
38 f(response)
39 }
40 }
41 }
42}
43
44impl<Op> Request<Op>
45where
46 Op: Operation,
47 Op::Output: for<'de> serde::de::Deserialize<'de>,
48{
49 pub fn serialize<F, Eff, T>(self, effect: F) -> (Eff, ResolveSerialized<T>)
56 where
57 F: FnOnce(Op) -> Eff,
58 T: FfiFormat,
59 {
60 let handle = self.handle.deserializing(move |response| {
62 T::deserialize(response).map_err(BridgeError::DeserializeOutput)
63 });
64
65 (effect(self.operation), handle)
66 }
67}
68
69impl<Out> RequestHandle<Out> {
70 fn deserializing<F, T>(self, mut func: F) -> ResolveSerialized<T>
73 where
74 F: (FnMut(&[u8]) -> Result<Out, BridgeError<T>>) + Send + Sync + 'static,
75 T: FfiFormat,
76 Out: 'static,
77 {
78 match self {
79 Self::Never => ResolveSerialized::Never,
80 Self::Once(resolve) => ResolveSerialized::Once(Box::new(move |response| {
81 let out = func(response)?;
82 resolve(out);
83 Ok(())
84 })),
85 Self::Many(resolve) => ResolveSerialized::Many(Box::new(move |response| {
86 let out = func(response)?;
87 resolve(out).map_err(|()| BridgeError::ProcessResponse(ResolveError::FinishedMany))
88 })),
89 }
90 }
91}