crux_core/bridge/
registry.rs1use std::sync::Mutex;
2
3use facet::Facet;
4use serde::{Deserialize, Serialize};
5use slab::Slab;
6
7use super::{BridgeError, FfiFormat, Request};
8use crate::bridge::request_serde::ResolveSerialized;
9use crate::{EffectFFI, ResolveError};
10
11#[allow(clippy::unsafe_derive_deserialize)]
12#[derive(Facet, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
13#[serde(transparent)]
14#[facet(transparent)]
15pub struct EffectId(pub u32);
16
17pub struct ResolveRegistry<T: FfiFormat>(Mutex<Slab<ResolveSerialized<T>>>);
18
19impl<T: FfiFormat> Default for ResolveRegistry<T> {
20 fn default() -> Self {
21 Self(Mutex::new(Slab::with_capacity(1024)))
22 }
23}
24
25impl<T: FfiFormat> ResolveRegistry<T> {
26 pub fn register<Eff>(&self, effect: Eff) -> Request<Eff::Ffi>
39 where
40 Eff: EffectFFI,
41 {
42 let (effect, resolve) = effect.serialize();
43
44 let id = self
45 .0
46 .lock()
47 .expect("Registry Mutex poisoned.")
48 .insert(resolve);
49
50 Request {
51 id: EffectId(id.try_into().expect("EffectId overflow")),
52 effect,
53 }
54 }
55 pub fn resume(&self, id: EffectId, response: &[u8]) -> Result<(), BridgeError<T>> {
68 let mut registry_lock = self.0.lock().expect("Registry Mutex poisoned");
69
70 let entry = registry_lock.get_mut(id.0 as usize);
71
72 let Some(entry) = entry else {
73 return Err(BridgeError::ProcessResponse(ResolveError::NotFound(
74 id.0.into(),
75 )));
76 };
77
78 let resolved = entry.resolve(response);
79
80 if matches!(entry, ResolveSerialized::Never) {
81 registry_lock.remove(id.0 as usize);
82 }
83
84 resolved
85 }
86}